gmp 0.1.7
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 +47 -0
- data/INSTALL +4 -0
- data/README.rdoc +257 -0
- data/ext/extconf.rb +30 -0
- data/ext/gmp.c +195 -0
- data/ext/gmpf.c +584 -0
- data/ext/gmpf.h +144 -0
- data/ext/gmpq.c +774 -0
- data/ext/gmpq.h +12 -0
- data/ext/gmpz.c +1774 -0
- data/ext/gmpz.h +20 -0
- data/ext/ruby_gmp.h +199 -0
- data/ext/takeover.h +36 -0
- data/manual.tex +183 -0
- data/test/README +41 -0
- data/test/tc_cmp.rb +74 -0
- data/test/tc_fib_fac_nextprime.rb +51 -0
- data/test/tc_floor_ceil_truncate.rb +21 -0
- data/test/tc_logical_roots.rb +48 -0
- data/test/tc_q.rb +27 -0
- data/test/tc_q_basic.rb +41 -0
- data/test/tc_sgn_neg_abs.rb +47 -0
- data/test/tc_swap.rb +19 -0
- data/test/tc_z.rb +71 -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/tc_z_shifts_last_bits.rb +22 -0
- data/test/tc_z_to_d_to_i.rb +24 -0
- data/test/tc_zerodivisionexceptions.rb +17 -0
- data/test/test_helper.rb +2 -0
- data/test/unit_tests.rb +135 -0
- metadata +89 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
0.1.6.2:
|
2
|
+
* Added optional argument to GMP::Z.to_s. Supply base as either a Fixnum or
|
3
|
+
a Symbol like :hex to get the string in a different base.
|
4
|
+
|
5
|
+
0.1.6:
|
6
|
+
* Tested on OS X 10.5.8 with Ruby 1.9.1. It's a go!
|
7
|
+
* Tested on LinuxMint 7 with Ruby 1.8.7. It's a go! Ping me if you have Linux
|
8
|
+
problems.
|
9
|
+
* Added documentation.
|
10
|
+
* Cleaned up source.
|
11
|
+
* Added tests: tc_swap, tc_floor_ceil_truncate, tc_to_i_to_d
|
12
|
+
|
13
|
+
0.1.5:
|
14
|
+
* Merged in reorg changes: Files like gmpz.c allow for documenting the C
|
15
|
+
extension methods.
|
16
|
+
* A good portion of the documentation has been written, may not be included
|
17
|
+
yet, but can be generated with
|
18
|
+
rdoc README.rdoc ext/*.c ext/*.h
|
19
|
+
|
20
|
+
0.1.4:
|
21
|
+
* Fixed a lot of gemspec problems
|
22
|
+
* Many more tests
|
23
|
+
* Tested on OS X 10.5.8
|
24
|
+
|
25
|
+
0.1.1:
|
26
|
+
* Attempting to revitalize through GitHub
|
27
|
+
* no changes to code yet
|
28
|
+
* modernizing files, eg with new ruby standards, towards a gem
|
29
|
+
|
30
|
+
1.0:
|
31
|
+
* MPFR support
|
32
|
+
* better string conversion
|
33
|
+
* Debian package
|
34
|
+
|
35
|
+
alpha9:
|
36
|
+
* more GMP::F code
|
37
|
+
* GMP::Z division
|
38
|
+
|
39
|
+
alpha8:
|
40
|
+
* various minor changes
|
41
|
+
|
42
|
+
alpha7:
|
43
|
+
* more GMP::F code
|
44
|
+
|
45
|
+
alpha6:
|
46
|
+
* basic support for GMP::F
|
47
|
+
* various minor changes
|
data/INSTALL
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,257 @@
|
|
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. The following environments have been tested by me:
|
50
|
+
gmp gem 0.1.4.2 on:
|
51
|
+
+-------------------------------------+-------------------+-----------+
|
52
|
+
| Platform | Ruby | GMP |
|
53
|
+
+-------------------------------------+-------------------+-----------+
|
54
|
+
| Cygwin on x86 | (MRI) Ruby 1.8.7 | GMP 4.3.1 |
|
55
|
+
| Linux (LinuxMint 7) on x86 (32-bit) | (MRI) Ruby 1.8.7 | GMP 4.3.1 |
|
56
|
+
| Mac OS X 10.5.7 on x86 (32-bit) | (MRI) Ruby 1.8.6 | GMP 4.3.1 |
|
57
|
+
| Mac OS X 10.5.7 on x86 (32-bit) | (MRI) Ruby 1.9.1 | GMP 4.3.1 |
|
58
|
+
+-------------------------------------+-------------------+-----------+
|
59
|
+
|
60
|
+
<b>Note:</b> To get this running on Mac OS X (32-bit), I compiled GMP 4.3.1 with:
|
61
|
+
./configure ABI=32 --disable-dependency-tracking
|
62
|
+
|
63
|
+
=Authors
|
64
|
+
|
65
|
+
* Tomasz Wegrzanowski
|
66
|
+
* srawlins
|
67
|
+
|
68
|
+
=Classes
|
69
|
+
|
70
|
+
It provides module GMP with following classes:
|
71
|
+
* GMP::Z - infinite precision integer numbers
|
72
|
+
* GMP::Q - infinite precision rational numbers
|
73
|
+
* GMP::F - arbitrary precision floating point numbers
|
74
|
+
|
75
|
+
Numbers are created by using new().
|
76
|
+
Constructors can take following arguments:
|
77
|
+
|
78
|
+
GMP::Z.new()
|
79
|
+
GMP::Z.new(GMP::Z)
|
80
|
+
GMP::Z.new(FixNum)
|
81
|
+
GMP::Z.new(BigNum)
|
82
|
+
GMP::Z.new(String)
|
83
|
+
GMP::Q.new()
|
84
|
+
GMP::Q.new(GMP::Q)
|
85
|
+
GMP::Q.new(String)
|
86
|
+
GMP::Q.new(any GMP::Z initializer)
|
87
|
+
GMP::Q.new(any GMP::Z initializer, any GMP::Z initializer)
|
88
|
+
GMP::F.new()
|
89
|
+
GMP::F.new(GMP::Z, precision=0)
|
90
|
+
GMP::F.new(GMP::Q, precision=0)
|
91
|
+
GMP::F.new(GMP::F)
|
92
|
+
GMP::F.new(GMP::F, precision)
|
93
|
+
GMP::F.new(String, precision=0)
|
94
|
+
GMP::F.new(FixNum, precision=0)
|
95
|
+
GMP::F.new(BigNum, precision=0)
|
96
|
+
GMP::F.new(Float, precision=0)
|
97
|
+
|
98
|
+
You can also call them as:
|
99
|
+
GMP.Z(args)
|
100
|
+
GMP.Q(args)
|
101
|
+
todo GMP.F(args)
|
102
|
+
|
103
|
+
=Methods
|
104
|
+
|
105
|
+
GMP::Z, GMP::Q and GMP::F
|
106
|
+
+ addition
|
107
|
+
- substraction
|
108
|
+
* multiplication
|
109
|
+
to_s convert to string. For GMP::Z, this method takes
|
110
|
+
one optional argument, a base. The base can be a
|
111
|
+
Fixnum in the ranges [2, 62] or [-36, -2] or a
|
112
|
+
Symbol: :bin, :oct, :dec, or :hex.
|
113
|
+
-@ negation
|
114
|
+
neg! in-place negation
|
115
|
+
abs absolute value
|
116
|
+
asb! in-place absolute value
|
117
|
+
coerce promotion of arguments
|
118
|
+
== equality test
|
119
|
+
<=>,>=,>,<=,< comparisions
|
120
|
+
class methods of GMP::Z
|
121
|
+
fac(n) factorial of n
|
122
|
+
fib(n) nth fibonacci number
|
123
|
+
pow(n,m) n to mth power
|
124
|
+
GMP::Z and GMP::Q
|
125
|
+
swap efficiently swap contents of two objects, there
|
126
|
+
is no GMP::F.swap because various GMP::F objects
|
127
|
+
may have different precisions, which would make
|
128
|
+
them unswapable
|
129
|
+
GMP::Z
|
130
|
+
.add! in-place addition
|
131
|
+
.sub! in-place subtraction
|
132
|
+
tdiv,fdiv,cdiv truncate, floor and ceil division
|
133
|
+
tmod,fmod,cmod truncate, floor and ceil modulus
|
134
|
+
.[],[]= testing and setting bits (as booleans)
|
135
|
+
scan0,scan1 starting at bitnr (1st arg), scan for a 0 or 1
|
136
|
+
(respectively), then return the index of the
|
137
|
+
first instance.
|
138
|
+
com 2's complement
|
139
|
+
com! in-place 2's complement
|
140
|
+
&,|,^ logical operations: and, or, xor
|
141
|
+
** power
|
142
|
+
powmod power modulo
|
143
|
+
even? is even
|
144
|
+
odd? is odd
|
145
|
+
<< shift left
|
146
|
+
>> shift right, floor
|
147
|
+
tshr shift right, truncate
|
148
|
+
lastbits_pos(n) last n bits of object, modulo if negative
|
149
|
+
lastbits_sgn(n) last n bits of object, preserve sign
|
150
|
+
power? is perfect power
|
151
|
+
square? is perfect square
|
152
|
+
sqrt square root
|
153
|
+
sqrt! change the object into its square root
|
154
|
+
sqrtrem square root, remainder
|
155
|
+
root(n) nth root
|
156
|
+
jacobi jacobi symbol
|
157
|
+
legendre legendre symbol
|
158
|
+
probab_prime? 0 if composite, 1 if probably prime, 2 if
|
159
|
+
certainly prime
|
160
|
+
nextprime next *probable* prime
|
161
|
+
nextprime! change the object into its next *probable* prime
|
162
|
+
popcount the number of bits equal to 1
|
163
|
+
to_i convert to FixNum or BigNum
|
164
|
+
remove(n) remove all occurences of factor n
|
165
|
+
GMP::Q and GMP::F
|
166
|
+
/ division
|
167
|
+
GMP::Q
|
168
|
+
num numerator
|
169
|
+
den denominator
|
170
|
+
inv inversion
|
171
|
+
inv! in-place inversion
|
172
|
+
floor,ceil,trunc nearest integer
|
173
|
+
class methods of GMP::F
|
174
|
+
default_prec get default precision
|
175
|
+
default_prec= set default precision
|
176
|
+
GMP::F
|
177
|
+
prec get precision
|
178
|
+
floor,ceil,trunc nearest integer, GMP::F is returned, not GMP::Z
|
179
|
+
floor!,ceil!,trunc! in-place nearest integer
|
180
|
+
GMP::F (only if MPFR is available)
|
181
|
+
exp e^object
|
182
|
+
expm1 the same as (object.exp) - 1, with better precision
|
183
|
+
log natural logarithm of object
|
184
|
+
log2 binary logarithm of object
|
185
|
+
log10 decimal logarithm of object
|
186
|
+
log1p the same as (object + 1).log, with better precision
|
187
|
+
sqrt square root of the object
|
188
|
+
cos \
|
189
|
+
sin |
|
190
|
+
tan |
|
191
|
+
acos |
|
192
|
+
asin |
|
193
|
+
atan | trigonometric functions
|
194
|
+
cosh | of the object
|
195
|
+
sinh |
|
196
|
+
tanh |
|
197
|
+
aconh |
|
198
|
+
asinh |
|
199
|
+
atanh /
|
200
|
+
nan? \
|
201
|
+
infinite? | type of floating point number
|
202
|
+
finite? |
|
203
|
+
number? /
|
204
|
+
** power
|
205
|
+
|
206
|
+
=Known Issues
|
207
|
+
|
208
|
+
* GMP::Z#pow does not appear to be working at all. Looking at the code, I don't
|
209
|
+
think it ever did.
|
210
|
+
|
211
|
+
=Precision
|
212
|
+
|
213
|
+
Precision can be explicitely set as second argument for GMP::F.new().
|
214
|
+
|
215
|
+
If there is no explicit precision, highest precision of all GMP::F arguments is
|
216
|
+
used. That doesn't ensure that result will be exact. For details, consult any
|
217
|
+
paper about floating point arithmetics.
|
218
|
+
|
219
|
+
Default precision can be explicitely set by passing 0 to GMP::F.new(). In
|
220
|
+
particular, you can set precision of copy of GMP::F object by:
|
221
|
+
new_obj = GMP::F.new(old_obj, 0)
|
222
|
+
|
223
|
+
Precision argument, and default_precision will be rounded up to whatever GMP
|
224
|
+
thinks is appropriate.
|
225
|
+
|
226
|
+
=Todo
|
227
|
+
|
228
|
+
These are inherited from Tomasz. I will go through these and see which are
|
229
|
+
still relevant.
|
230
|
+
|
231
|
+
* mpz_fits_* and 31 vs. 32 integer variables
|
232
|
+
* all appropriate module and class methods if there are any to add
|
233
|
+
* fix all sign issues (don't know what these are)
|
234
|
+
* floats with precision control
|
235
|
+
* random numbers
|
236
|
+
* to_s vs. inspect
|
237
|
+
* check if mpz_addmul_ui would optimize some statements
|
238
|
+
* some system that allows using denref and numref as normal ruby objects
|
239
|
+
* should we allocate global temporary variables like Perl GMP does?
|
240
|
+
* takeover code that replaces all Bignums with GMP::Z
|
241
|
+
* better bignum parser
|
242
|
+
* zero-copy method for strings generation
|
243
|
+
* put rb_raise into nice macros
|
244
|
+
* benchmarks against Python GMP and Perl GMP
|
245
|
+
* dup methods
|
246
|
+
* integrate F into system
|
247
|
+
* should Z.[] bits be 0/1 or true/false, 0 is true, what might badly surprise users
|
248
|
+
* seriously investigate Ruby Makefile-making system
|
249
|
+
* any2small_integer()
|
250
|
+
* check asm output, especially local memory efficiency
|
251
|
+
* it might be better to use `register' for some local variables
|
252
|
+
* powm with negative exponents
|
253
|
+
* check if different sorting of operatations gives better cache usage
|
254
|
+
* GMP::* op RubyFloat and RubyFloat op GMP::*
|
255
|
+
* sort checks
|
256
|
+
* check all new GMP4 operations
|
257
|
+
* GMP::Q.to_s(base), GMP::F.to_s(base)
|
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,195 @@
|
|
1
|
+
/*
|
2
|
+
* gmp.c
|
3
|
+
*
|
4
|
+
* This file contains everything you would expect from a C extension.
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <ruby_gmp.h>
|
8
|
+
|
9
|
+
VALUE mGMP, cGMP_Z, cGMP_Q, cGMP_F;
|
10
|
+
|
11
|
+
void r_gmpz_free(void *ptr) { mpz_clear (ptr); free (ptr); }
|
12
|
+
void r_gmpq_free(void *ptr) { mpq_clear (ptr); free (ptr); }
|
13
|
+
void r_gmpf_free(void *ptr) { mpf_clear (ptr); free (ptr); }
|
14
|
+
|
15
|
+
static void mpq_str_set(MP_RAT *ROP, char *str)
|
16
|
+
{
|
17
|
+
int i=0;
|
18
|
+
|
19
|
+
while (str[i] && str[i] != '/')
|
20
|
+
i++;
|
21
|
+
|
22
|
+
if (str[i])
|
23
|
+
{
|
24
|
+
str[i] = 0; /* You didn't see that :) */
|
25
|
+
mpz_set_str (mpq_numref(ROP), str, 0);
|
26
|
+
str[i] = '/';
|
27
|
+
mpz_set_str (mpq_denref(ROP), str+i+1, 0);
|
28
|
+
} else {
|
29
|
+
mpz_set_str (mpq_numref(ROP), str, 0);
|
30
|
+
mpz_set_ui (mpq_denref(ROP), 1);
|
31
|
+
}
|
32
|
+
mpq_canonicalize (ROP);
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
|
36
|
+
{
|
37
|
+
MP_RAT *self_val, *arg_val;
|
38
|
+
|
39
|
+
if (argc != 0) {
|
40
|
+
mpq_get_struct(self, self_val);
|
41
|
+
if (argc == 1 && GMPQ_P(argv[0])) {
|
42
|
+
mpq_get_struct(argv[0], arg_val);
|
43
|
+
mpq_set (self_val, arg_val);
|
44
|
+
} else if (argc == 1 && STRING_P(argv[0])) {
|
45
|
+
mpq_str_set (self_val, STR2CSTR(argv[0]));
|
46
|
+
} else {
|
47
|
+
mpz_set_value (mpq_numref(self_val), argv[0]);
|
48
|
+
if (argc == 2) {
|
49
|
+
mpz_set_value (mpq_denref(self_val), argv[1]);
|
50
|
+
mpq_canonicalize(self_val);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
return Qnil;
|
55
|
+
}
|
56
|
+
|
57
|
+
/* don't pass GMP::F here, it should be handled separately */
|
58
|
+
void mpf_set_value(MP_FLOAT *self_val, VALUE arg)
|
59
|
+
{
|
60
|
+
MP_RAT *arg_val_q;
|
61
|
+
MP_INT *arg_val_z;
|
62
|
+
|
63
|
+
if (GMPQ_P(arg)) {
|
64
|
+
mpq_get_struct(arg, arg_val_q);
|
65
|
+
mpf_set_q(self_val, arg_val_q);
|
66
|
+
} else if (GMPZ_P(arg)) {
|
67
|
+
mpz_get_struct(arg, arg_val_z);
|
68
|
+
mpf_set_z(self_val, arg_val_z);
|
69
|
+
} else if (FLOAT_P(arg)) {
|
70
|
+
mpf_set_d(self_val, NUM2DBL(arg));
|
71
|
+
} else if (FIXNUM_P(arg)) {
|
72
|
+
mpf_set_si(self_val, FIX2INT(arg));
|
73
|
+
} else if (STRING_P(arg)) {
|
74
|
+
if (mpf_set_str(self_val, STR2CSTR(arg), 10) == -1) {
|
75
|
+
rb_raise(rb_eRuntimeError, "Badly formatted string");
|
76
|
+
}
|
77
|
+
} else if (BIGNUM_P(arg)) {
|
78
|
+
#if 1 /* GMP3 code */
|
79
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
80
|
+
mpf_set_z(self_val, arg_val_z);
|
81
|
+
mpz_temp_free(arg_val_z);
|
82
|
+
#endif
|
83
|
+
} else {
|
84
|
+
rb_raise(rb_eTypeError, "Don't know how to convert %s into GMP::F", rb_class2name(rb_class_of(arg)));
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
static VALUE r_gmpz_coerce(VALUE self, VALUE arg)
|
89
|
+
{
|
90
|
+
return rb_assoc_new(r_gmpzsg_new(1, &arg, cGMP_Z), self);
|
91
|
+
}
|
92
|
+
|
93
|
+
static VALUE r_gmpq_coerce(VALUE self, VALUE arg)
|
94
|
+
{
|
95
|
+
return rb_assoc_new(r_gmpqsg_new(1, &arg, cGMP_Q), self);
|
96
|
+
}
|
97
|
+
|
98
|
+
static VALUE r_gmpf_coerce(VALUE self, VALUE arg)
|
99
|
+
{
|
100
|
+
return rb_assoc_new(r_gmpfsg_new(1, &arg, cGMP_F), self);
|
101
|
+
}
|
102
|
+
|
103
|
+
static VALUE r_gmpfsg_get_default_prec(VALUE klass)
|
104
|
+
{
|
105
|
+
(void)klass;
|
106
|
+
return INT2NUM(mpf_get_default_prec());
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
|
110
|
+
{
|
111
|
+
(void)klass;
|
112
|
+
if (FIXNUM_P(arg)) {
|
113
|
+
if (FIX2INT(arg) <= 0) {
|
114
|
+
rb_raise(rb_eRangeError, "prec must be positive");
|
115
|
+
}
|
116
|
+
mpf_set_default_prec (FIX2INT(arg));
|
117
|
+
} else {
|
118
|
+
rb_raise(rb_eTypeError, "prec must be FixNum");
|
119
|
+
}
|
120
|
+
return Qnil;
|
121
|
+
}
|
122
|
+
|
123
|
+
#include "gmpf.h"
|
124
|
+
#include "gmpq.h"
|
125
|
+
/* #include "gmpz.h" */
|
126
|
+
#include "takeover.h"
|
127
|
+
|
128
|
+
#define REGISTER_TAKEOVER(fname, ruby_fname, old_fname) \
|
129
|
+
rb_define_alias(rb_cFixnum, old_fname, ruby_fname); \
|
130
|
+
rb_define_method(rb_cFixnum, ruby_fname, takeover_fixnum_##fname, -1); \
|
131
|
+
rb_define_alias(rb_cBignum, old_fname, ruby_fname); \
|
132
|
+
rb_define_method(rb_cBignum, ruby_fname, takeover_bignum_##fname, -1);
|
133
|
+
|
134
|
+
void Init_gmp() {
|
135
|
+
mGMP = rb_define_module("GMP");
|
136
|
+
rb_define_const(mGMP, "GMP_VERSION", rb_str_new2(gmp_version));
|
137
|
+
|
138
|
+
cGMP_Z = rb_define_class_under(mGMP, "Z", rb_cInteger);
|
139
|
+
init_gmpz();
|
140
|
+
rb_define_method(cGMP_Z, "coerce", r_gmpz_coerce, 1);
|
141
|
+
/*
|
142
|
+
rb_define_method(cGMP_Z, "gcd", r_gmpz_gcd, 1);
|
143
|
+
rb_define_method(cGMP_Z, "lcm", r_gmpz_lcm, 1);
|
144
|
+
*/
|
145
|
+
|
146
|
+
cGMP_Q = rb_define_class_under (mGMP, "Q", rb_cNumeric);
|
147
|
+
init_gmpq();
|
148
|
+
rb_define_method(cGMP_Q, "initialize", r_gmpq_initialize, -1);
|
149
|
+
rb_define_method(cGMP_Q, "coerce", r_gmpq_coerce, 1);
|
150
|
+
rb_define_method(cGMP_Q, "num", r_gmpq_num, 0);
|
151
|
+
rb_define_method(cGMP_Q, "den", r_gmpq_den, 0);
|
152
|
+
|
153
|
+
cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
|
154
|
+
init_gmpf();
|
155
|
+
rb_define_singleton_method(cGMP_F, "default_prec", r_gmpfsg_get_default_prec, 0);
|
156
|
+
rb_define_singleton_method(cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
|
157
|
+
rb_define_method(cGMP_F, "coerce", r_gmpf_coerce, 1); // new method - testing
|
158
|
+
|
159
|
+
/* rb_define_method(cGMP_F, "cmpabs", r_gmpf_cmpabs, 1);*/
|
160
|
+
|
161
|
+
#ifdef MPFR
|
162
|
+
rb_define_method(cGMP_F, "exp", r_gmpfr_exp, 0);
|
163
|
+
rb_define_method(cGMP_F, "log", r_gmpfr_log, 0);
|
164
|
+
rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, 0);
|
165
|
+
rb_define_method(cGMP_F, "cos", r_gmpfr_cos, 0);
|
166
|
+
rb_define_method(cGMP_F, "sin", r_gmpfr_sin, 0);
|
167
|
+
rb_define_method(cGMP_F, "tan", r_gmpfr_tan, 0);
|
168
|
+
rb_define_method(cGMP_F, "acos", r_gmpfr_acos, 0);
|
169
|
+
rb_define_method(cGMP_F, "asin", r_gmpfr_asin, 0);
|
170
|
+
rb_define_method(cGMP_F, "atan", r_gmpfr_atan, 0);
|
171
|
+
rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, 0);
|
172
|
+
rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, 0);
|
173
|
+
rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, 0);
|
174
|
+
rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, 0);
|
175
|
+
rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, 0);
|
176
|
+
rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, 0);
|
177
|
+
rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, 0);
|
178
|
+
rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, 0);
|
179
|
+
rb_define_method(cGMP_F, "log2", r_gmpfr_log2, 0);
|
180
|
+
rb_define_method(cGMP_F, "log10", r_gmpfr_log10, 0);
|
181
|
+
|
182
|
+
rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
|
183
|
+
rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
|
184
|
+
rb_define_method(cGMP_F, "finite?", r_gmpfr_fin_p, 0);
|
185
|
+
rb_define_method(cGMP_F, "number?", r_gmpfr_number_p, 0);
|
186
|
+
|
187
|
+
rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
|
188
|
+
#endif /* MPFR */
|
189
|
+
// more
|
190
|
+
|
191
|
+
REGISTER_TAKEOVER(and, "&", "old_and")
|
192
|
+
REGISTER_TAKEOVER(or, "|", "old_or")
|
193
|
+
REGISTER_TAKEOVER(xor, "^", "old_xor")
|
194
|
+
/* takeover cmpabs ? */
|
195
|
+
}
|