srawlins-gmp 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +23 -0
- data/INSTALL +4 -0
- data/README.rdoc +248 -0
- data/ext/extconf.rb +30 -0
- data/ext/gmp.c +561 -0
- data/ext/gmpf.h +442 -0
- data/ext/gmpq.h +486 -0
- data/ext/gmpz.h +833 -0
- data/ext/takeover.h +36 -0
- data/test/README +41 -0
- data/test/tc_cmp.rb +74 -0
- data/test/tc_q.rb +27 -0
- data/test/tc_q_basic.rb +41 -0
- data/test/tc_z.rb +59 -0
- data/test/tc_z_basic.rb +35 -0
- data/test/tc_z_exponentiation.rb +22 -0
- data/test/tc_z_logic.rb +54 -0
- data/test/test_helper.rb +2 -0
- data/test/unit_tests.rb +75 -0
- metadata +81 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
1.1.0:
|
2
|
+
* Attempting to revitalize through GitHub
|
3
|
+
* no changes to code yet
|
4
|
+
* modernizing files, eg with new ruby standards, towards a gem
|
5
|
+
|
6
|
+
1.0:
|
7
|
+
* MPFR support
|
8
|
+
* better string conversion
|
9
|
+
* Debian package
|
10
|
+
|
11
|
+
alpha9:
|
12
|
+
* more GMP::F code
|
13
|
+
* GMP::Z division
|
14
|
+
|
15
|
+
alpha8:
|
16
|
+
* various minor changes
|
17
|
+
|
18
|
+
alpha7:
|
19
|
+
* more GMP::F code
|
20
|
+
|
21
|
+
alpha6:
|
22
|
+
* basic support for GMP::F
|
23
|
+
* various minor changes
|
data/INSTALL
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
=gmp
|
2
|
+
|
3
|
+
gmp is library providing Ruby bindings to GMP library. Here is the introduction
|
4
|
+
paragraph at http://gmplib.org/#WHAT :
|
5
|
+
|
6
|
+
* "GMP is a free library for arbitrary precision arithmetic, operating on
|
7
|
+
signed integers, rational numbers, and floating point numbers. There is no
|
8
|
+
practical limit to the precision except the ones implied by the available
|
9
|
+
memory in the machine GMP runs on. GMP has a rich set of functions, and the
|
10
|
+
functions have a regular interface.
|
11
|
+
|
12
|
+
* The main target applications for GMP are cryptography applications and
|
13
|
+
research, Internet security applications, algebra systems, computational
|
14
|
+
algebra research, etc.
|
15
|
+
|
16
|
+
* GMP is carefully designed to be as fast as possible, both for small operands
|
17
|
+
and for huge operands. The speed is achieved by using fullwords as the basic
|
18
|
+
arithmetic type, by using fast algorithms, with highly optimised assembly
|
19
|
+
code for the most common inner loops for a lot of CPUs, and by a general
|
20
|
+
emphasis on speed.
|
21
|
+
|
22
|
+
* GMP is faster than any other bignum library. The advantage for GMP increases
|
23
|
+
with the operand sizes for many operations, since GMP uses asymptotically
|
24
|
+
faster algorithms.
|
25
|
+
|
26
|
+
* The first GMP release was made in 1991. It is continually developed and
|
27
|
+
maintained, with a new release about once a year.
|
28
|
+
|
29
|
+
* GMP is distributed under the GNU LGPL. This license makes the library free to
|
30
|
+
use, share, and improve, and allows you to pass on the result. The license
|
31
|
+
gives freedoms, but also sets firm restrictions on the use with non-free
|
32
|
+
programs.
|
33
|
+
|
34
|
+
* GMP is part of the GNU project. For more information about the GNU project,
|
35
|
+
please see the official GNU web site.
|
36
|
+
|
37
|
+
* GMP's main target platforms are Unix-type systems, such as GNU/Linux,
|
38
|
+
Solaris, HP-UX, Mac OS X/Darwin, BSD, AIX, etc. It also is known to work on
|
39
|
+
Windoze in 32-bit mode.
|
40
|
+
|
41
|
+
* GMP is brought to you by a team listed in the manual.
|
42
|
+
|
43
|
+
* GMP is carefully developed and maintained, both technically and legally. We
|
44
|
+
of course inspect and test contributed code carefully, but equally
|
45
|
+
importantly we make sure we have the legal right to distribute the
|
46
|
+
contributions, meaning users can safely use GMP. To achieve this, we will ask
|
47
|
+
contributors to sign paperwork where they allow us to distribute their work."
|
48
|
+
|
49
|
+
Only GMP 4 or newer is supported. It has been officially tested with:
|
50
|
+
|-------------------------------------|
|
51
|
+
| Platform | Ruby | GMP |
|
52
|
+
|---------------|---------|-----------|
|
53
|
+
| Cygwin on x86 | 1.8.6 | GMP 4.3.1 |
|
54
|
+
|-------------------------------------|
|
55
|
+
|
56
|
+
I have not tested one wit on Ruby 1.9.x, but my educated guess is, no, it
|
57
|
+
does not behave. If only because of rubyio.h replacing ruby/io.h. This is on my
|
58
|
+
todo list. I intend to use RMagick as a guide.
|
59
|
+
|
60
|
+
=Authors
|
61
|
+
|
62
|
+
* Tomasz Wegrzanowski
|
63
|
+
* srawlins
|
64
|
+
|
65
|
+
=Classes
|
66
|
+
|
67
|
+
It provides module GMP with following classes:
|
68
|
+
* GMP::Z - infitite precision integer numbers
|
69
|
+
* GMP::Q - infitite precision rational numbers
|
70
|
+
* GMP::F - arbitrary precision floating point numbers
|
71
|
+
|
72
|
+
Numbers are created by using new().
|
73
|
+
Constructors can take following arguments:
|
74
|
+
|
75
|
+
GMP::Z.new()
|
76
|
+
GMP::Z.new(GMP::Z)
|
77
|
+
GMP::Z.new(FixNum)
|
78
|
+
GMP::Z.new(BigNum)
|
79
|
+
GMP::Z.new(String)
|
80
|
+
GMP::Q.new()
|
81
|
+
GMP::Q.new(GMP::Q)
|
82
|
+
GMP::Q.new(String)
|
83
|
+
GMP::Q.new(any GMP::Z initializer)
|
84
|
+
GMP::Q.new(any GMP::Z initializer, any GMP::Z initializer)
|
85
|
+
GMP::F.new()
|
86
|
+
GMP::F.new(GMP::Z, precision=0)
|
87
|
+
GMP::F.new(GMP::Q, precision=0)
|
88
|
+
GMP::F.new(GMP::F)
|
89
|
+
GMP::F.new(GMP::F, precision)
|
90
|
+
GMP::F.new(String, precision=0)
|
91
|
+
GMP::F.new(FixNum, precision=0)
|
92
|
+
GMP::F.new(BigNum, precision=0)
|
93
|
+
GMP::F.new(Float, precision=0)
|
94
|
+
|
95
|
+
You can also call them as:
|
96
|
+
GMP.Z(args)
|
97
|
+
GMP.Q(args)
|
98
|
+
todo GMP.F(args)
|
99
|
+
|
100
|
+
=Methods
|
101
|
+
|
102
|
+
GMP::Z, GMP::Q and GMP::F
|
103
|
+
+ addition
|
104
|
+
- substraction
|
105
|
+
* multiplication
|
106
|
+
to_s convert to string
|
107
|
+
-@ negation
|
108
|
+
neg! in-place negation
|
109
|
+
abs absolute value
|
110
|
+
asb! in-place absolute value
|
111
|
+
coerce promotion of arguments
|
112
|
+
== equality test
|
113
|
+
<=>,>=,>,<=,< comparisions
|
114
|
+
class methods of GMP::Z
|
115
|
+
fac(n) factorial of n
|
116
|
+
fib(n) nth fibonacci number
|
117
|
+
pow(n,m) n to mth power
|
118
|
+
GMP::Z and GMP::Q
|
119
|
+
swap efficiently swap contents of two objects, there
|
120
|
+
is no GMP::F.swap because various GMP::F objects
|
121
|
+
may have different precisions, which would make
|
122
|
+
them unswapable
|
123
|
+
GMP::Z
|
124
|
+
add! in-place addition
|
125
|
+
sub! in-place subtraction
|
126
|
+
tdiv,fdiv,cdiv truncate, floor and ceil division
|
127
|
+
tmod,fmod,cmod truncate, floor and ceil modulus
|
128
|
+
[],[]= testing and setting bits (as booleans)
|
129
|
+
scan0,scan1 starting at bitnr (1st arg), scan for a 0 or 1
|
130
|
+
(respectively), then return the index of the
|
131
|
+
first instance.
|
132
|
+
com 2's complement
|
133
|
+
com! in-place 2's complement
|
134
|
+
&,|,^ logical operations: and, or, xor
|
135
|
+
** power
|
136
|
+
powmod power modulo
|
137
|
+
even? is even
|
138
|
+
odd? is odd
|
139
|
+
<< shift left
|
140
|
+
>> shift right, floor
|
141
|
+
tshr shift right, truncate
|
142
|
+
lastbits_pos(n) last n bits of object, modulo if negative
|
143
|
+
lastbits_sgn(n) last n bits of object, preserve sign
|
144
|
+
power? is perfect power
|
145
|
+
square? is perfect square
|
146
|
+
sqrt square root
|
147
|
+
sqrt! change the object into its square root
|
148
|
+
root(n) nth root
|
149
|
+
jacobi jacobi symbol
|
150
|
+
legendre legendre symbol
|
151
|
+
probab_prime? 0 if composite, 1 if probably prime, 2 if
|
152
|
+
certainly prime
|
153
|
+
nextprime next *probable* prime
|
154
|
+
nextprime! change the object into its next *probable* prime
|
155
|
+
popcount the number of bits equal to 1
|
156
|
+
to_i convert to FixNum or BigNum
|
157
|
+
remove(n) remove all occurences of factor n
|
158
|
+
GMP::Q and GMP::F
|
159
|
+
/ division
|
160
|
+
GMP::Q
|
161
|
+
num numerator
|
162
|
+
den denominator
|
163
|
+
inv inversion
|
164
|
+
inv! in-place inversion
|
165
|
+
floor,ceil,trunc nearest integer
|
166
|
+
class methods of GMP::F
|
167
|
+
default_prec get default precision
|
168
|
+
default_prec= set default precision
|
169
|
+
GMP::F
|
170
|
+
prec get precision
|
171
|
+
floor,ceil,trunc nearest integer, GMP::F is returned, not GMP::Z
|
172
|
+
floor!,ceil!,trunc! in-place nearest integer
|
173
|
+
GMP::F (only if MPFR is available)
|
174
|
+
exp e^object
|
175
|
+
expm1 the same as (object.exp) - 1, with better precision
|
176
|
+
log natural logarithm of object
|
177
|
+
log2 binary logarithm of object
|
178
|
+
log10 decimal logarithm of object
|
179
|
+
log1p the same as (object + 1).log, with better precision
|
180
|
+
sqrt square root of the object
|
181
|
+
cos \
|
182
|
+
sin |
|
183
|
+
tan |
|
184
|
+
acos |
|
185
|
+
asin |
|
186
|
+
atan | trigonometric functions
|
187
|
+
cosh | of the object
|
188
|
+
sinh |
|
189
|
+
tanh |
|
190
|
+
aconh |
|
191
|
+
asinh |
|
192
|
+
atanh /
|
193
|
+
nan? \
|
194
|
+
infinite? | type of floating point number
|
195
|
+
finite? |
|
196
|
+
number? /
|
197
|
+
** power
|
198
|
+
|
199
|
+
=Precision
|
200
|
+
|
201
|
+
Precision can be explicitely set as second argument for GMP::F.new().
|
202
|
+
|
203
|
+
If there is no explicit precision, highest precision of all GMP::F arguments is
|
204
|
+
used. That doesn't ensure that result will be exact. For details, consult any
|
205
|
+
paper about floating point arithmetics.
|
206
|
+
|
207
|
+
Default precision can be explicitely set by passing 0 to GMP::F.new(). In
|
208
|
+
particular, you can set precision of copy of GMP::F object by:
|
209
|
+
new_obj = GMP::F.new(old_obj, 0)
|
210
|
+
|
211
|
+
Precision argument, and default_precision will be rounded up to whatever GMP
|
212
|
+
thinks is appropriate.
|
213
|
+
|
214
|
+
=Todo
|
215
|
+
|
216
|
+
These are inherited from Tomasz. I will go through these and see which are
|
217
|
+
still relevant.
|
218
|
+
|
219
|
+
* ruby 1.9.x
|
220
|
+
* mpz_fits_* and 31 vs. 32 integer variables
|
221
|
+
* all appropriate module and class methods if there are any to add
|
222
|
+
* fix all sign issues
|
223
|
+
* floats with precision control
|
224
|
+
* random numbers
|
225
|
+
* to_s vs. inspect ?
|
226
|
+
* to_s_hex(), or more-ruby-ish, to_s(:hex)
|
227
|
+
* check if mpz_addmul_ui would optimize some statements
|
228
|
+
* some system that allow using denref and numref as normal ruby objects
|
229
|
+
* should we allocate global temporary variables like Perl GMP do ?
|
230
|
+
* takeover code that replaces all Bignums with GMP::Z
|
231
|
+
* better bignum parser
|
232
|
+
* zero-copy method for strings generation
|
233
|
+
* what should be ancestors of GMP::* classes ?
|
234
|
+
* division and modulo
|
235
|
+
* put rb_raise into nice macros
|
236
|
+
* benchmarks against Python GMP and Perl GMP
|
237
|
+
* dup methods
|
238
|
+
* integrate F into system
|
239
|
+
* should Z.[] bits be 0/1 or true/false, 0 is true, what might badly surprise users
|
240
|
+
* seriously investigate Ruby Makefile-making system
|
241
|
+
* any2small_integer()
|
242
|
+
* check asm output, especially local memory efficiency
|
243
|
+
* it might be better to use `register' for some local variables
|
244
|
+
* powm with negative exponents
|
245
|
+
* check if different sorting of operatations gives better cache usage,
|
246
|
+
* GMP::* op RubyFloat and RubyFloat op GMP::*
|
247
|
+
* sort checks
|
248
|
+
* check all new GMP4 operations
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mkmf'
|
4
|
+
|
5
|
+
dir_config('gmp')
|
6
|
+
dir_config('mpfr')
|
7
|
+
|
8
|
+
ok = true
|
9
|
+
unless have_header('gmp.h')
|
10
|
+
$stderr.puts "can't find gmp.h, try --with-gmp-include=<path>"
|
11
|
+
ok = false
|
12
|
+
end
|
13
|
+
|
14
|
+
unless have_library('gmp', '__gmpz_init')
|
15
|
+
$stderr.puts "can't find -lgmp, try --with-gmp-lib=<path>"
|
16
|
+
ok = false
|
17
|
+
end
|
18
|
+
|
19
|
+
if (have_header('mpfr.h') and
|
20
|
+
have_header('mpf2mpfr.h') and
|
21
|
+
have_library('mpfr', 'mpfr_init'))
|
22
|
+
$CFLAGS += ' -DMPFR'
|
23
|
+
end
|
24
|
+
|
25
|
+
$CFLAGS += ' -Wall -W -O6 -g'
|
26
|
+
if ok
|
27
|
+
create_makefile('gmp')
|
28
|
+
else
|
29
|
+
raise "Unable to build, correct above errors and rerun"
|
30
|
+
end
|
data/ext/gmp.c
ADDED
@@ -0,0 +1,561 @@
|
|
1
|
+
/*
|
2
|
+
* gmp.c
|
3
|
+
*
|
4
|
+
* This file contains everything you would expect from a C extension.
|
5
|
+
*/
|
6
|
+
|
7
|
+
#define _GNU_SOURCE
|
8
|
+
#include <stdio.h>
|
9
|
+
|
10
|
+
#include <ruby.h>
|
11
|
+
#include <gmp.h>
|
12
|
+
|
13
|
+
#ifdef MPFR
|
14
|
+
|
15
|
+
#ifdef HAVE_MPFR_H
|
16
|
+
#include <mpfr.h>
|
17
|
+
#endif /* HAVE_MPFR_H */
|
18
|
+
|
19
|
+
#ifdef HAVE_MPF2MPFR_H
|
20
|
+
#include <mpf2mpfr.h>
|
21
|
+
#endif /* HAVE_MPF2MPFR_H */
|
22
|
+
|
23
|
+
#endif /* MPFR */
|
24
|
+
|
25
|
+
#include <stdlib.h>
|
26
|
+
|
27
|
+
/*
|
28
|
+
MP_INT*, MP_RAT* and MP_FLOAT* are used because they don't have side-effects
|
29
|
+
of single-element arrays mp*_t
|
30
|
+
|
31
|
+
MP_FLOAT is defined here, as it's commented out in gmp.h
|
32
|
+
*/
|
33
|
+
#if defined(MPFR) && defined(HAVE_MPFR_H)
|
34
|
+
typedef __mpfr_struct MP_FLOAT;
|
35
|
+
#else
|
36
|
+
typedef __mpf_struct MP_FLOAT;
|
37
|
+
#endif /* HAVE_MPF2MPFR_H */
|
38
|
+
|
39
|
+
#define mpz_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_INT, c_var); }
|
40
|
+
#define mpq_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_RAT, c_var); }
|
41
|
+
#define mpf_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_FLOAT, c_var); }
|
42
|
+
#define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpf_get_prec(c_var); }
|
43
|
+
#define mpz_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Z, MP_INT, 0, r_gmpz_free, c_var); }
|
44
|
+
#define mpq_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Q, MP_RAT, 0, r_gmpq_free, c_var); }
|
45
|
+
#define mpf_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_F, MP_FLOAT, 0, r_gmpf_free, c_var); }
|
46
|
+
#define mpz_make_struct_init(ruby_var,c_var) { mpz_make_struct(ruby_var,c_var); mpz_init (c_var); }
|
47
|
+
#define mpq_make_struct_init(ruby_var,c_var) { mpq_make_struct(ruby_var,c_var); mpq_init (c_var); }
|
48
|
+
#define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpf_init2 (c_var,prec); }
|
49
|
+
#define BIGNUM_P(value) (TYPE(value) == T_BIGNUM)
|
50
|
+
#define FLOAT_P(value) (TYPE(value) == T_FLOAT)
|
51
|
+
#define STRING_P(value) (TYPE(value) == T_STRING)
|
52
|
+
#define GMPZ_P(value) (rb_obj_is_instance_of(value, cGMP_Z) == Qtrue)
|
53
|
+
#define GMPQ_P(value) (rb_obj_is_instance_of(value, cGMP_Q) == Qtrue)
|
54
|
+
#define GMPF_P(value) (rb_obj_is_instance_of(value, cGMP_F) == Qtrue)
|
55
|
+
#define mpz_set_bignum(var_mpz,var_bignum) \
|
56
|
+
mpz_set_str (var_mpz, STR2CSTR (rb_funcall (var_bignum, rb_intern ("to_s"), 0)), 0);
|
57
|
+
#define mpz_temp_alloc(var) { var=malloc(sizeof(MP_INT)); }
|
58
|
+
#define mpz_temp_init(var) { mpz_temp_alloc(var); mpz_init(var); }
|
59
|
+
#define mpz_temp_from_bignum(var,var_bignum) \
|
60
|
+
{ mpz_temp_alloc(var); mpz_init_set_str (var, STR2CSTR (rb_funcall (var_bignum, rb_intern ("to_s"), 0)), 0); }
|
61
|
+
#define mpz_temp_free(var) { mpz_clear(var); free(var); }
|
62
|
+
#define mpf_temp_alloc(var) { var=malloc(sizeof(MP_FLOAT)); }
|
63
|
+
#define mpf_temp_init(var,prec) { mpf_temp_alloc(var); mpf_init2(var,prec); }
|
64
|
+
#define mpf_temp_free(var) { mpf_clear(var); free(var); }
|
65
|
+
#define FLT2DBL(var) (RFLOAT(var)->value)
|
66
|
+
#define prec_max(prec,var) {if(mpf_get_prec(var) > prec) prec = mpf_get_prec(var); }
|
67
|
+
|
68
|
+
#define EXPECTED_ZQFXBD "Expected GMP::Z, GMP::Q, GMP::F, FixNum, BigNum or Float"
|
69
|
+
#define EXPECTED_ZQFXB "Expected GMP::Z, GMP::Q, GMP::F, FixNum or BigNum"
|
70
|
+
#define EXPECTED_ZXB "Expected GMP::Z, FixNum or BigNum"
|
71
|
+
#define EXPECTED_ZX "Expected GMP::Z or FixNum"
|
72
|
+
#define EXPECTED_X "Expected FixNum"
|
73
|
+
#define typeerror(expected) rb_raise(rb_eTypeError, EXPECTED_##expected)
|
74
|
+
#define typeerror_as(expected, argname) rb_raise(rb_eTypeError, EXPECTED_##expected " as " argname)
|
75
|
+
|
76
|
+
//should change exception type
|
77
|
+
#define not_yet rb_raise(rb_eTypeError,"Not implemented yet")
|
78
|
+
|
79
|
+
VALUE mGMP, cGMP_Z, cGMP_Q, cGMP_F;
|
80
|
+
|
81
|
+
static void r_gmpz_free(void *ptr) { mpz_clear (ptr); free (ptr); }
|
82
|
+
static void r_gmpq_free(void *ptr) { mpq_clear (ptr); free (ptr); }
|
83
|
+
static void r_gmpf_free(void *ptr) { mpf_clear (ptr); free (ptr); }
|
84
|
+
|
85
|
+
static VALUE r_gmpzsg_new(int argc, VALUE *argv, VALUE klass)
|
86
|
+
{
|
87
|
+
MP_INT *res_val;
|
88
|
+
VALUE res;
|
89
|
+
|
90
|
+
(void)klass;
|
91
|
+
|
92
|
+
if (argc > 1)
|
93
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)", argc);
|
94
|
+
|
95
|
+
mpz_make_struct (res, res_val);
|
96
|
+
mpz_init (res_val);
|
97
|
+
|
98
|
+
rb_obj_call_init(res, argc, argv);
|
99
|
+
|
100
|
+
return res;
|
101
|
+
}
|
102
|
+
|
103
|
+
static VALUE r_gmpqsg_new(int argc, VALUE *argv, VALUE klass)
|
104
|
+
{
|
105
|
+
MP_RAT *res_val;
|
106
|
+
VALUE res;
|
107
|
+
|
108
|
+
(void)klass;
|
109
|
+
|
110
|
+
if (argc > 2)
|
111
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1 or 2)", argc);
|
112
|
+
|
113
|
+
mpq_make_struct (res, res_val);
|
114
|
+
mpq_init (res_val);
|
115
|
+
rb_obj_call_init(res, argc, argv);
|
116
|
+
|
117
|
+
return res;
|
118
|
+
}
|
119
|
+
|
120
|
+
static VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass)
|
121
|
+
{
|
122
|
+
MP_FLOAT *res_val;
|
123
|
+
VALUE res;
|
124
|
+
|
125
|
+
(void)klass;
|
126
|
+
|
127
|
+
if (argc > 2)
|
128
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1 or 2)", argc);
|
129
|
+
|
130
|
+
mpf_make_struct (res, res_val);
|
131
|
+
rb_obj_call_init(res, argc, argv);
|
132
|
+
|
133
|
+
return res;
|
134
|
+
}
|
135
|
+
|
136
|
+
static void mpz_set_value(MP_INT *target, VALUE source)
|
137
|
+
{
|
138
|
+
MP_INT *source_val;
|
139
|
+
|
140
|
+
if (GMPZ_P(source)) {
|
141
|
+
mpz_get_struct(source, source_val);
|
142
|
+
mpz_set (target, source_val);
|
143
|
+
} else if (FIXNUM_P(source)) {
|
144
|
+
mpz_set_si (target, NUM2INT(source));
|
145
|
+
} else if (STRING_P(source)) {
|
146
|
+
mpz_set_str (target, STR2CSTR(source), 0);
|
147
|
+
} else if (BIGNUM_P(source)) {
|
148
|
+
mpz_set_bignum(target, source);
|
149
|
+
} else {
|
150
|
+
rb_raise (rb_eTypeError, "Don't know how to convert %s into GMP_Z", rb_class2name(rb_class_of(source)));
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
static VALUE r_gmpz_initialize(int argc, VALUE *argv, VALUE self)
|
155
|
+
{
|
156
|
+
MP_INT *self_val;
|
157
|
+
|
158
|
+
if (argc != 0) {
|
159
|
+
mpz_get_struct(self,self_val);
|
160
|
+
mpz_set_value (self_val, argv[0]);
|
161
|
+
}
|
162
|
+
return Qnil;
|
163
|
+
}
|
164
|
+
|
165
|
+
static void mpq_str_set(MP_RAT *ROP, char *str)
|
166
|
+
{
|
167
|
+
int i=0;
|
168
|
+
|
169
|
+
while (str[i] && str[i] != '/')
|
170
|
+
i++;
|
171
|
+
|
172
|
+
if (str[i])
|
173
|
+
{
|
174
|
+
str[i] = 0; /* You didn't see that :) */
|
175
|
+
mpz_set_str (mpq_numref(ROP), str, 0);
|
176
|
+
str[i] = '/';
|
177
|
+
mpz_set_str (mpq_denref(ROP), str+i+1, 0);
|
178
|
+
} else {
|
179
|
+
mpz_set_str (mpq_numref(ROP), str, 0);
|
180
|
+
mpz_set_ui (mpq_denref(ROP), 1);
|
181
|
+
}
|
182
|
+
mpq_canonicalize (ROP);
|
183
|
+
}
|
184
|
+
|
185
|
+
|
186
|
+
static VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
|
187
|
+
{
|
188
|
+
MP_RAT *self_val, *arg_val;
|
189
|
+
|
190
|
+
if (argc != 0) {
|
191
|
+
mpq_get_struct(self, self_val);
|
192
|
+
if (argc == 1 && GMPQ_P(argv[0])) {
|
193
|
+
mpq_get_struct(argv[0], arg_val);
|
194
|
+
mpq_set (self_val, arg_val);
|
195
|
+
} else if (argc == 1 && STRING_P(argv[0])) {
|
196
|
+
mpq_str_set (self_val, STR2CSTR(argv[0]));
|
197
|
+
} else {
|
198
|
+
mpz_set_value (mpq_numref(self_val), argv[0]);
|
199
|
+
if (argc == 2) {
|
200
|
+
mpz_set_value (mpq_denref(self_val), argv[1]);
|
201
|
+
mpq_canonicalize(self_val);
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
return Qnil;
|
206
|
+
}
|
207
|
+
|
208
|
+
/* don't pass GMP::F here, it should be handled separately */
|
209
|
+
static void mpf_set_value(MP_FLOAT *self_val, VALUE arg)
|
210
|
+
{
|
211
|
+
MP_RAT *arg_val_q;
|
212
|
+
MP_INT *arg_val_z;
|
213
|
+
|
214
|
+
if (GMPQ_P(arg)) {
|
215
|
+
mpq_get_struct (arg, arg_val_q);
|
216
|
+
mpf_set_q(self_val, arg_val_q);
|
217
|
+
} else if (GMPZ_P(arg)) {
|
218
|
+
mpz_get_struct (arg, arg_val_z);
|
219
|
+
mpf_set_z(self_val, arg_val_z);
|
220
|
+
} else if (FLOAT_P(arg)) {
|
221
|
+
mpf_set_d(self_val, FLT2DBL(arg));
|
222
|
+
} else if (FIXNUM_P(arg)) {
|
223
|
+
mpf_set_si(self_val, FIX2INT(arg));
|
224
|
+
} else if (STRING_P(arg)) {
|
225
|
+
if (mpf_set_str(self_val, STR2CSTR(arg), 10) == -1) {
|
226
|
+
rb_raise (rb_eRuntimeError, "Badly formatted string");
|
227
|
+
}
|
228
|
+
} else if (BIGNUM_P(arg)) {
|
229
|
+
#if 1 /* GMP3 code */
|
230
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
231
|
+
mpf_set_z(self_val, arg_val_z);
|
232
|
+
mpz_temp_free(arg_val_z);
|
233
|
+
#endif
|
234
|
+
} else {
|
235
|
+
rb_raise (rb_eTypeError, "Don't know how to convert %s into GMP::F", rb_class2name(rb_class_of(arg)));
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
static VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
240
|
+
{
|
241
|
+
MP_FLOAT *self_val, *arg_val_f;
|
242
|
+
unsigned long prec = 0;
|
243
|
+
VALUE arg;
|
244
|
+
|
245
|
+
mpf_get_struct (self, self_val);
|
246
|
+
|
247
|
+
if (argc==0) {
|
248
|
+
mpf_init(self_val);
|
249
|
+
mpf_set_si(self_val, 0);
|
250
|
+
return Qnil;
|
251
|
+
}
|
252
|
+
|
253
|
+
arg = argv[0];
|
254
|
+
|
255
|
+
if (argc == 2) {
|
256
|
+
if (FIXNUM_P(argv[1])) {
|
257
|
+
if (FIX2INT(argv[1]) >= 0)
|
258
|
+
prec = FIX2INT(argv[1]);
|
259
|
+
else
|
260
|
+
rb_raise(rb_eRangeError, "prec must be non-negative");
|
261
|
+
} else {
|
262
|
+
rb_raise(rb_eTypeError, "prec must be FixNum");
|
263
|
+
}
|
264
|
+
} else if (GMPF_P(arg)) {
|
265
|
+
mpf_get_struct (arg, arg_val_f);
|
266
|
+
prec = mpf_get_prec (arg_val_f);
|
267
|
+
}
|
268
|
+
if (prec == 0)
|
269
|
+
mpf_init (self_val);
|
270
|
+
else
|
271
|
+
mpf_init2 (self_val, prec);
|
272
|
+
|
273
|
+
if (GMPF_P(arg)) {
|
274
|
+
mpf_get_struct (arg, arg_val_f);
|
275
|
+
mpf_set(self_val, arg_val_f);
|
276
|
+
} else {
|
277
|
+
mpf_set_value(self_val, arg);
|
278
|
+
}
|
279
|
+
|
280
|
+
return Qnil;
|
281
|
+
}
|
282
|
+
|
283
|
+
/*
|
284
|
+
* call-seq: to_s()
|
285
|
+
*
|
286
|
+
* Converts this mpq_t object to a Ruby string.
|
287
|
+
*/
|
288
|
+
static VALUE r_gmpq_to_s(VALUE self)
|
289
|
+
{
|
290
|
+
MP_RAT *self_val;
|
291
|
+
MP_INT *self_val_num, *self_val_den;
|
292
|
+
char *str;
|
293
|
+
VALUE res;
|
294
|
+
int sizeinbase;
|
295
|
+
int offset;
|
296
|
+
|
297
|
+
Data_Get_Struct(self, MP_RAT, self_val);
|
298
|
+
|
299
|
+
if (mpz_cmp_ui(mpq_denref(self_val), 1) == 0) {
|
300
|
+
str = mpz_get_str(NULL, 10, mpq_numref (self_val));
|
301
|
+
res = rb_str_new2(str);
|
302
|
+
free (str);
|
303
|
+
return res;
|
304
|
+
}
|
305
|
+
|
306
|
+
self_val_num = mpq_numref(self_val);
|
307
|
+
self_val_den = mpq_denref(self_val);
|
308
|
+
|
309
|
+
sizeinbase = mpz_sizeinbase (self_val_num, 10) + mpz_sizeinbase (self_val_den, 10) + 3;
|
310
|
+
str = malloc (sizeinbase);
|
311
|
+
|
312
|
+
mpz_get_str (str, 10, self_val_num);
|
313
|
+
offset = strlen (str);
|
314
|
+
str[offset] = '/';
|
315
|
+
mpz_get_str (str + offset + 1, 10, self_val_den);
|
316
|
+
res = rb_str_new2(str);
|
317
|
+
free (str);
|
318
|
+
|
319
|
+
return res;
|
320
|
+
}
|
321
|
+
|
322
|
+
static VALUE r_gmpz_coerce(VALUE self, VALUE arg)
|
323
|
+
{
|
324
|
+
return rb_assoc_new(r_gmpzsg_new(1, &arg, cGMP_Z), self);
|
325
|
+
}
|
326
|
+
|
327
|
+
static VALUE r_gmpq_coerce(VALUE self, VALUE arg)
|
328
|
+
{
|
329
|
+
return rb_assoc_new(r_gmpqsg_new(1, &arg, cGMP_Q), self);
|
330
|
+
}
|
331
|
+
|
332
|
+
static VALUE r_gmpf_coerce(VALUE self, VALUE arg)
|
333
|
+
{
|
334
|
+
return rb_assoc_new(r_gmpfsg_new(1, &arg, cGMP_F), self);
|
335
|
+
}
|
336
|
+
|
337
|
+
static VALUE r_gmpmod_z(int argc, VALUE *argv, VALUE module)
|
338
|
+
{
|
339
|
+
(void)module;
|
340
|
+
return r_gmpzsg_new(argc, argv, cGMP_Z);
|
341
|
+
}
|
342
|
+
|
343
|
+
static VALUE r_gmpmod_q(int argc, VALUE *argv, VALUE module)
|
344
|
+
{
|
345
|
+
(void)module;
|
346
|
+
return r_gmpqsg_new(argc, argv, cGMP_Q);
|
347
|
+
}
|
348
|
+
|
349
|
+
static VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module)
|
350
|
+
{
|
351
|
+
(void)module;
|
352
|
+
return r_gmpfsg_new(argc, argv, cGMP_F);
|
353
|
+
}
|
354
|
+
|
355
|
+
static VALUE r_gmpfsg_get_default_prec(VALUE klass)
|
356
|
+
{
|
357
|
+
(void)klass;
|
358
|
+
return INT2NUM(mpf_get_default_prec());
|
359
|
+
}
|
360
|
+
|
361
|
+
static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
|
362
|
+
{
|
363
|
+
(void)klass;
|
364
|
+
if (FIXNUM_P(arg)) {
|
365
|
+
if (FIX2INT(arg) <= 0) {
|
366
|
+
rb_raise(rb_eRangeError, "prec must be positive");
|
367
|
+
}
|
368
|
+
mpf_set_default_prec (FIX2INT(arg));
|
369
|
+
} else {
|
370
|
+
rb_raise(rb_eTypeError, "prec must be FixNum");
|
371
|
+
}
|
372
|
+
return Qnil;
|
373
|
+
}
|
374
|
+
|
375
|
+
#include "gmpf.h"
|
376
|
+
#include "gmpq.h"
|
377
|
+
#include "gmpz.h"
|
378
|
+
#include "takeover.h"
|
379
|
+
|
380
|
+
#define REGISTER_TAKEOVER(fname, ruby_fname, old_fname) \
|
381
|
+
rb_define_alias(rb_cFixnum, old_fname, ruby_fname); \
|
382
|
+
rb_define_method(rb_cFixnum, ruby_fname, takeover_fixnum_##fname, -1); \
|
383
|
+
rb_define_alias(rb_cBignum, old_fname, ruby_fname); \
|
384
|
+
rb_define_method(rb_cBignum, ruby_fname, takeover_bignum_##fname, -1);
|
385
|
+
|
386
|
+
void Init_gmp () {
|
387
|
+
mGMP = rb_define_module("GMP");
|
388
|
+
rb_define_module_function(mGMP, "Z", r_gmpmod_z, -1);
|
389
|
+
rb_define_module_function(mGMP, "Q", r_gmpmod_q, -1);
|
390
|
+
rb_define_module_function(mGMP, "F", r_gmpmod_f, -1);
|
391
|
+
|
392
|
+
cGMP_Z = rb_define_class_under(mGMP, "Z", rb_cInteger);
|
393
|
+
rb_define_singleton_method(cGMP_Z, "new", r_gmpzsg_new, -1);
|
394
|
+
rb_define_singleton_method(cGMP_Z, "fib", r_gmpzsg_fib, 1);
|
395
|
+
rb_define_singleton_method(cGMP_Z, "fac", r_gmpzsg_fac, 1);
|
396
|
+
rb_define_singleton_method(cGMP_Z, "pow", r_gmpzsg_pow, 2);
|
397
|
+
rb_define_method(cGMP_Z, "initialize", r_gmpz_initialize, -1);
|
398
|
+
rb_define_method(cGMP_Z, "to_s", r_gmpz_to_s, 0);
|
399
|
+
rb_define_method(cGMP_Z, "coerce", r_gmpz_coerce, 1);
|
400
|
+
rb_define_method(cGMP_Z, "+", r_gmpz_add, 1);
|
401
|
+
rb_define_method(cGMP_Z, "add!", r_gmpz_add_self, 1);
|
402
|
+
rb_define_method(cGMP_Z, "-", r_gmpz_sub, 1);
|
403
|
+
rb_define_method(cGMP_Z, "sub!", r_gmpz_sub_self, 1);
|
404
|
+
rb_define_method(cGMP_Z, "*", r_gmpz_mul, 1);
|
405
|
+
rb_define_method(cGMP_Z, "/", r_gmpz_div, 1);
|
406
|
+
rb_define_method(cGMP_Z, "tdiv", r_gmpz_tdiv, 1);
|
407
|
+
rb_define_method(cGMP_Z, "tmod", r_gmpz_tmod, 1);
|
408
|
+
rb_define_method(cGMP_Z, "fdiv", r_gmpz_fdiv, 1);
|
409
|
+
rb_define_method(cGMP_Z, "fmod", r_gmpz_fmod, 1);
|
410
|
+
rb_define_method(cGMP_Z, "cdiv", r_gmpz_cdiv, 1);
|
411
|
+
rb_define_method(cGMP_Z, "cmod", r_gmpz_cmod, 1);
|
412
|
+
rb_define_method(cGMP_Z, "-@", r_gmpz_neg, 0);
|
413
|
+
rb_define_method(cGMP_Z, "neg", r_gmpz_neg, 0);
|
414
|
+
rb_define_method(cGMP_Z, "neg!", r_gmpz_neg_self, 0);
|
415
|
+
rb_define_method(cGMP_Z, "abs", r_gmpz_abs, 0);
|
416
|
+
rb_define_method(cGMP_Z, "abs!", r_gmpz_abs_self, 0);
|
417
|
+
rb_define_method(cGMP_Z, "com", r_gmpz_com, 0);
|
418
|
+
rb_define_method(cGMP_Z, "com!", r_gmpz_com_self, 0);
|
419
|
+
rb_define_method(cGMP_Z, "&", r_gmpz_and, 1);
|
420
|
+
rb_define_method(cGMP_Z, "|", r_gmpz_or, 1);
|
421
|
+
rb_define_method(cGMP_Z, "^", r_gmpz_xor, 1);
|
422
|
+
rb_define_method(cGMP_Z, "[]=", r_gmpz_setbit, 2);
|
423
|
+
rb_define_method(cGMP_Z, "[]", r_gmpz_getbit, 1);
|
424
|
+
rb_define_method(cGMP_Z, "scan0", r_gmpz_scan0, 1);
|
425
|
+
rb_define_method(cGMP_Z, "scan1", r_gmpz_scan1, 1);
|
426
|
+
rb_define_method(cGMP_Z, "**", r_gmpz_pow, 1);
|
427
|
+
rb_define_method(cGMP_Z, "powmod", r_gmpz_powm, 2);
|
428
|
+
rb_define_method(cGMP_Z, "even?", r_gmpz_is_even, 0);
|
429
|
+
rb_define_method(cGMP_Z, "odd?", r_gmpz_is_odd, 0);
|
430
|
+
rb_define_method(cGMP_Z, "sgn", r_gmpz_sgn, 0);
|
431
|
+
rb_define_method(cGMP_Z, "<=>", r_gmpz_cmp, 1);
|
432
|
+
rb_define_method(cGMP_Z, ">", r_gmpz_cmp_gt, 1);
|
433
|
+
rb_define_method(cGMP_Z, ">=", r_gmpz_cmp_ge, 1);
|
434
|
+
rb_define_method(cGMP_Z, "<", r_gmpz_cmp_lt, 1);
|
435
|
+
rb_define_method(cGMP_Z, "<=", r_gmpz_cmp_le, 1);
|
436
|
+
rb_define_method(cGMP_Z, "==", r_gmpz_eq, 1);
|
437
|
+
rb_define_method(cGMP_Z, ">>", r_gmpz_fshr, 1);
|
438
|
+
rb_define_method(cGMP_Z, "<<", r_gmpz_shl, 1);
|
439
|
+
rb_define_method(cGMP_Z, "tshr", r_gmpz_tshr, 1);
|
440
|
+
rb_define_method(cGMP_Z, "lastbits_sgn", r_gmpz_tshrm, 1);
|
441
|
+
rb_define_method(cGMP_Z, "lastbits_pos", r_gmpz_fshrm, 1);
|
442
|
+
rb_define_method(cGMP_Z, "square?", r_gmpz_is_square, 0);
|
443
|
+
rb_define_method(cGMP_Z, "power?", r_gmpz_is_power, 0);
|
444
|
+
rb_define_method(cGMP_Z, "swap", r_gmpz_swap, 1);
|
445
|
+
rb_define_method(cGMP_Z, "sqrt", r_gmpz_sqrt, 0);
|
446
|
+
rb_define_method(cGMP_Z, "sqrt!", r_gmpz_sqrt_self, 0);
|
447
|
+
rb_define_method(cGMP_Z, "sqrtrem", r_gmpz_sqrtrem, 0);
|
448
|
+
rb_define_method(cGMP_Z, "jacobi", r_gmpz_jacobi, 0);
|
449
|
+
rb_define_method(cGMP_Z, "legendre", r_gmpz_legendre, 0);
|
450
|
+
rb_define_method(cGMP_Z, "probab_prime?", r_gmpz_is_probab_prime, -1);
|
451
|
+
rb_define_method(cGMP_Z, "nextprime", r_gmpz_nextprime, 0);
|
452
|
+
rb_define_method(cGMP_Z, "nextprime!", r_gmpz_nextprime_self, 0);
|
453
|
+
rb_define_method(cGMP_Z, "popcount", r_gmpz_popcount, 0);
|
454
|
+
rb_define_method(cGMP_Z, "to_d", r_gmpz_to_d, 0);
|
455
|
+
rb_define_method(cGMP_Z, "root", r_gmpz_root, 1);
|
456
|
+
rb_define_method(cGMP_Z, "remove", r_gmpz_remove, 1);
|
457
|
+
rb_define_method(cGMP_Z, "to_i", r_gmpz_to_i, 0);
|
458
|
+
rb_define_method(cGMP_Z, "cmpabs", r_gmpz_cmpabs, 1);
|
459
|
+
/*
|
460
|
+
rb_define_method(cGMP_Z, "gcd", r_gmpz_gcd, 1);
|
461
|
+
rb_define_method(cGMP_Z, "lcm", r_gmpz_lcm, 1);
|
462
|
+
*/
|
463
|
+
cGMP_Q = rb_define_class_under (mGMP, "Q", rb_cNumeric);
|
464
|
+
rb_define_singleton_method(cGMP_Q, "new", r_gmpqsg_new, -1);
|
465
|
+
rb_define_method(cGMP_Q, "initialize", r_gmpq_initialize, -1);
|
466
|
+
rb_define_method(cGMP_Q, "to_s", r_gmpq_to_s, 0);
|
467
|
+
rb_define_method(cGMP_Q, "coerce", r_gmpq_coerce, 1);
|
468
|
+
rb_define_method(cGMP_Q, "num", r_gmpq_num, 0);
|
469
|
+
rb_define_method(cGMP_Q, "den", r_gmpq_den, 0);
|
470
|
+
rb_define_method(cGMP_Q, "+", r_gmpq_add, 1);
|
471
|
+
rb_define_method(cGMP_Q, "-", r_gmpq_sub, 1);
|
472
|
+
rb_define_method(cGMP_Q, "*", r_gmpq_mul, 1);
|
473
|
+
rb_define_method(cGMP_Q, "/", r_gmpq_div, 1);
|
474
|
+
rb_define_method(cGMP_Q, "inv", r_gmpq_inv, 0);
|
475
|
+
rb_define_method(cGMP_Q, "inv!", r_gmpq_inv_self, 0);
|
476
|
+
rb_define_method(cGMP_Q, "-@", r_gmpq_neg, 0);
|
477
|
+
rb_define_method(cGMP_Q, "neg!", r_gmpq_neg_self, 0);
|
478
|
+
rb_define_method(cGMP_Q, "abs", r_gmpq_abs, 0);
|
479
|
+
rb_define_method(cGMP_Q, "abs!", r_gmpq_abs_self, 0);
|
480
|
+
rb_define_method(cGMP_Q, "sgn", r_gmpq_sgn, 0);
|
481
|
+
rb_define_method(cGMP_Q, "<=>", r_gmpq_cmp, 1);
|
482
|
+
rb_define_method(cGMP_Q, ">", r_gmpq_cmp_gt, 1);
|
483
|
+
rb_define_method(cGMP_Q, ">=", r_gmpq_cmp_ge, 1);
|
484
|
+
rb_define_method(cGMP_Q, "<", r_gmpq_cmp_lt, 1);
|
485
|
+
rb_define_method(cGMP_Q, "<=", r_gmpq_cmp_le, 1);
|
486
|
+
rb_define_method(cGMP_Q, "==", r_gmpq_eq, 1);
|
487
|
+
rb_define_method(cGMP_Q, "swap", r_gmpq_swap, 1);
|
488
|
+
rb_define_method(cGMP_Q, "floor", r_gmpq_floor, 0);
|
489
|
+
rb_define_method(cGMP_Q, "ceil", r_gmpq_ceil, 0);
|
490
|
+
rb_define_method(cGMP_Q, "trunc", r_gmpq_trunc, 0);
|
491
|
+
rb_define_method(cGMP_Q, "to_d", r_gmpq_to_d, 0);
|
492
|
+
rb_define_method(cGMP_Q, "cmpabs", r_gmpq_cmpabs, 1);
|
493
|
+
|
494
|
+
cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
|
495
|
+
rb_define_singleton_method(cGMP_F, "new", r_gmpfsg_new, -1);
|
496
|
+
rb_define_singleton_method(cGMP_F, "default_prec", r_gmpfsg_get_default_prec, 0);
|
497
|
+
rb_define_singleton_method(cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
|
498
|
+
rb_define_method(cGMP_F, "initialize", r_gmpf_initialize, -1);
|
499
|
+
rb_define_method(cGMP_F, "to_s", r_gmpf_to_s, 0);
|
500
|
+
rb_define_method(cGMP_F, "coerce", r_gmpf_coerce, 1); // new method - testing
|
501
|
+
rb_define_method(cGMP_F, "+", r_gmpf_add, 1);
|
502
|
+
rb_define_method(cGMP_F, "-", r_gmpf_sub, 1);
|
503
|
+
rb_define_method(cGMP_F, "*", r_gmpf_mul, 1);
|
504
|
+
rb_define_method(cGMP_F, "/", r_gmpf_div, 1);
|
505
|
+
rb_define_method(cGMP_F, "-@", r_gmpf_neg, 0);
|
506
|
+
rb_define_method(cGMP_F, "neg!", r_gmpf_neg_self, 0);
|
507
|
+
rb_define_method(cGMP_F, "abs", r_gmpf_abs, 0);
|
508
|
+
rb_define_method(cGMP_F, "abs!", r_gmpf_abs_self, 0);
|
509
|
+
rb_define_method(cGMP_F, "sgn", r_gmpf_sgn, 0);
|
510
|
+
rb_define_method(cGMP_F, "<=>", r_gmpf_cmp, 1);
|
511
|
+
rb_define_method(cGMP_F, ">", r_gmpf_cmp_gt, 1);
|
512
|
+
rb_define_method(cGMP_F, ">=", r_gmpf_cmp_ge, 1);
|
513
|
+
rb_define_method(cGMP_F, "<", r_gmpf_cmp_lt, 1);
|
514
|
+
rb_define_method(cGMP_F, "<=", r_gmpf_cmp_le, 1);
|
515
|
+
rb_define_method(cGMP_F, "==", r_gmpf_eq, 1);
|
516
|
+
rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
|
517
|
+
rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);
|
518
|
+
rb_define_method(cGMP_F, "ceil", r_gmpf_ceil, 0);
|
519
|
+
rb_define_method(cGMP_F, "ceil!", r_gmpf_ceil_self, 0);
|
520
|
+
rb_define_method(cGMP_F, "trunc", r_gmpf_trunc, 0);
|
521
|
+
rb_define_method(cGMP_F, "trunc!", r_gmpf_trunc_self, 0);
|
522
|
+
rb_define_method(cGMP_F, "to_d", r_gmpf_to_d, 0);
|
523
|
+
rb_define_method(cGMP_F, "prec", r_gmpf_get_prec, 0);
|
524
|
+
|
525
|
+
/* rb_define_method(cGMP_F, "cmpabs", r_gmpf_cmpabs, 1);*/
|
526
|
+
|
527
|
+
#ifdef MPFR
|
528
|
+
rb_define_method(cGMP_F, "exp", r_gmpfr_exp, 0);
|
529
|
+
rb_define_method(cGMP_F, "log", r_gmpfr_log, 0);
|
530
|
+
rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, 0);
|
531
|
+
rb_define_method(cGMP_F, "cos", r_gmpfr_cos, 0);
|
532
|
+
rb_define_method(cGMP_F, "sin", r_gmpfr_sin, 0);
|
533
|
+
rb_define_method(cGMP_F, "tan", r_gmpfr_tan, 0);
|
534
|
+
rb_define_method(cGMP_F, "acos", r_gmpfr_acos, 0);
|
535
|
+
rb_define_method(cGMP_F, "asin", r_gmpfr_asin, 0);
|
536
|
+
rb_define_method(cGMP_F, "atan", r_gmpfr_atan, 0);
|
537
|
+
rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, 0);
|
538
|
+
rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, 0);
|
539
|
+
rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, 0);
|
540
|
+
rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, 0);
|
541
|
+
rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, 0);
|
542
|
+
rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, 0);
|
543
|
+
rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, 0);
|
544
|
+
rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, 0);
|
545
|
+
rb_define_method(cGMP_F, "log2", r_gmpfr_log2, 0);
|
546
|
+
rb_define_method(cGMP_F, "log10", r_gmpfr_log10, 0);
|
547
|
+
|
548
|
+
rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
|
549
|
+
rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
|
550
|
+
rb_define_method(cGMP_F, "finite?", r_gmpfr_fin_p, 0);
|
551
|
+
rb_define_method(cGMP_F, "number?", r_gmpfr_number_p, 0);
|
552
|
+
|
553
|
+
rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
|
554
|
+
#endif /* MPFR */
|
555
|
+
// more
|
556
|
+
|
557
|
+
REGISTER_TAKEOVER(and, "&", "old_and")
|
558
|
+
REGISTER_TAKEOVER(or, "|", "old_or")
|
559
|
+
REGISTER_TAKEOVER(xor, "^", "old_xor")
|
560
|
+
/* takeover cmpabs ? */
|
561
|
+
}
|