gmp 0.6.19 → 0.6.31
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/README.html +23 -8
- data/README.markdown +22 -8
- data/benchmark/benchmark-results-5.1.0_0.6.19.ods +0 -0
- data/ext/extconf.rb +12 -1
- data/ext/gmpf.c +1 -1
- data/ext/gmpz.c +127 -72
- data/ext/ruby_gmp.h +1 -1
- data/{performance.html → performance.2012.html} +0 -0
- data/{performance.md → performance.2012.md} +0 -0
- data/{performance.pdf → performance.2012.pdf} +0 -0
- data/test/gmp_tprintf.rb +1 -1
- data/test/gmp_troot.rb +58 -0
- data/test/mpfr_tsqrt.rb +24 -24
- data/test/tc_z_io.rb +5 -0
- data/test/unit_tests.rb +1 -0
- metadata +7 -5
data/CHANGELOG
CHANGED
data/README.html
CHANGED
@@ -98,7 +98,7 @@ by me: gmp gem 0.5.47 on:</p>
|
|
98
98
|
GMP 5.0.1 (3.0.0)</td>
|
99
99
|
</tr>
|
100
100
|
<tr>
|
101
|
-
<td rowspan="
|
101
|
+
<td rowspan="3">Mac OS X 10.6.8 on x86_64 (64-bit)</td>
|
102
102
|
<td>(MRI) Ruby 1.8.7</td>
|
103
103
|
<td>GMP 4.3.2 (2.4.2)<br />
|
104
104
|
GMP 5.0.5 (3.1.1)</td>
|
@@ -253,6 +253,7 @@ GMP::Z
|
|
253
253
|
tmod,fmod,cmod truncate, floor and ceil modulus
|
254
254
|
>> shift right, floor
|
255
255
|
divisible?(b) true if divisible by b
|
256
|
+
congruent?(c,d) true if congruent to c modulus d
|
256
257
|
** power
|
257
258
|
powmod power modulo
|
258
259
|
\[\],\[\]= testing and setting bits (as booleans)
|
@@ -287,6 +288,10 @@ GMP::Z
|
|
287
288
|
remove(n) remove all occurences of factor n
|
288
289
|
popcount the number of bits equal to 1
|
289
290
|
hamdist the hamming distance between two integers
|
291
|
+
out_raw output to IO object
|
292
|
+
inp_raw input from IO object
|
293
|
+
export export to a byte array (String)
|
294
|
+
import import from a byte array (String)
|
290
295
|
sizeinbase(b) digits in base b
|
291
296
|
size_in_bin digits in binary
|
292
297
|
size number of limbs
|
@@ -409,7 +414,7 @@ a #=> 30
|
|
409
414
|
|
410
415
|
<ul>
|
411
416
|
<li><a href="https://github.com/srawlins/gmp">This README</a></li>
|
412
|
-
<li>Loren Segal and the guys at RubyGems.org are
|
417
|
+
<li>Loren Segal and the guys at RubyGems.org are awesome: <a href="http://rubydoc.info/gems/gmp/frames">YARDoc</a>.</li>
|
413
418
|
<li>There should be a manual.pdf <a href="https://github.com/srawlins/gmp/blob/master/manual.pdf">here</a>. I spend waaay too much time working on this, but it looks very pretty.</li>
|
414
419
|
<li><a href="https://github.com/srawlins/gmp/blob/master/CHANGELOG">CHANGELOG</a></li>
|
415
420
|
</ul>
|
@@ -433,11 +438,21 @@ MPFR=no-mpfr rake report
|
|
433
438
|
|
434
439
|
<h2>Known Issues</h2>
|
435
440
|
|
436
|
-
<
|
437
|
-
|
438
|
-
|
439
|
-
<
|
440
|
-
|
441
|
+
<p>Don't call <code>GMP::RandState(:lc_2exp_size)</code>. Give a 2nd arg.
|
442
|
+
Don't use multiple assignment (<code>a = b = GMP::Z(0)</code>) with functional mappings:</p>
|
443
|
+
|
444
|
+
<p><code>ruby
|
445
|
+
>> a = b = GMP::Z(0)
|
446
|
+
=> 0
|
447
|
+
>> GMP::Z.mul(a, GMP::Z(2), GMP::Z(3))
|
448
|
+
=> nil
|
449
|
+
>> a
|
450
|
+
=> 6
|
451
|
+
>> b
|
452
|
+
=> 6
|
453
|
+
</code></p>
|
454
|
+
|
455
|
+
<p>JRuby has some interesting bugs and flickering tests. GMP::Z(GMP::GMP<em>NUMB</em>MAX) for example, blows up.</p>
|
441
456
|
|
442
457
|
<h2>Precision</h2>
|
443
458
|
|
@@ -457,7 +472,7 @@ MPFR=no-mpfr rake report
|
|
457
472
|
<h2>Todo</h2>
|
458
473
|
|
459
474
|
<ul>
|
460
|
-
<li><code>GMP::Z#to_d_2exp</code>, <code>#
|
475
|
+
<li><code>GMP::Z#to_d_2exp</code>, <code>#rootrem</code>, <code>#kronecker</code>, <code>#bin</code>, <code>#fib2</code>, <code>#lucnum</code>, <code>#lucnum2</code>, <code>#combit</code>, <code>#fits_x?</code></li>
|
461
476
|
<li><code>GMP::Q#to_s(base)</code>, <code>GMP::F#to_s(base)</code> (test it!)</li>
|
462
477
|
<li>benchmark pi</li>
|
463
478
|
<li>a butt-load of functional mappings. 47-ish sets.</li>
|
data/README.markdown
CHANGED
@@ -271,8 +271,9 @@ Methods
|
|
271
271
|
square? is perfect square
|
272
272
|
sqrt square root
|
273
273
|
sqrt! change the object into its square root
|
274
|
-
sqrtrem square root, remainder
|
274
|
+
sqrtrem square root, with remainder
|
275
275
|
root(n) nth root
|
276
|
+
rootrem(n) nth root, with remainder
|
276
277
|
probab_prime? 0 if composite, 1 if probably prime, 2 if
|
277
278
|
certainly prime
|
278
279
|
nextprime next *probable* prime
|
@@ -432,9 +433,22 @@ You can also use the following shiny new rake tasks:
|
|
432
433
|
Known Issues
|
433
434
|
------------
|
434
435
|
|
435
|
-
|
436
|
-
|
437
|
-
|
436
|
+
Don't call `GMP::RandState(:lc_2exp_size)`. Give a 2nd arg.
|
437
|
+
|
438
|
+
Don't use multiple assignment (`a = b = GMP::Z(0)`) with functional mappings:
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
>> a = b = GMP::Z(0)
|
442
|
+
=> 0
|
443
|
+
>> GMP::Z.mul(a, GMP::Z(2), GMP::Z(3))
|
444
|
+
=> nil
|
445
|
+
>> a
|
446
|
+
=> 6
|
447
|
+
>> b
|
448
|
+
=> 6
|
449
|
+
```
|
450
|
+
|
451
|
+
JRuby has some interesting bugs and flickering tests. GMP::Z(GMP::GMP_NUMB_MAX) for example, blows up.
|
438
452
|
|
439
453
|
Precision
|
440
454
|
---------
|
@@ -450,12 +464,12 @@ Precision argument, and default_precision will be rounded up to whatever GMP thi
|
|
450
464
|
Benchmarking
|
451
465
|
------------
|
452
466
|
|
453
|
-
Please see [performance](performance.md)
|
467
|
+
Please see [performance](https://github.com/srawlins/gmp/blob/master/performance.md) on GitHub.
|
454
468
|
|
455
469
|
Todo
|
456
470
|
----
|
457
471
|
|
458
|
-
* `GMP::Z#to_d_2exp`, `#
|
472
|
+
* `GMP::Z#to_d_2exp`, `#kronecker`, `#bin`, `#fib2`, `#lucnum`, `#lucnum2`, `#combit`, `#fits_x?`
|
459
473
|
* `GMP::Q#to_s(base)`, `GMP::F#to_s(base)` (test it!)
|
460
474
|
* benchmark pi
|
461
475
|
* a butt-load of functional mappings. 47-ish sets.
|
@@ -463,14 +477,14 @@ Todo
|
|
463
477
|
* beef up `r_gmpq_initialize`; I don't like to rely on `mpz_set_value`.
|
464
478
|
* finish compile-results.rb
|
465
479
|
* New in MPFR 3.1.0: mpfr_frexp, mpfr_grandom, mpfr_z_sub, divide-by-zero exception (?)
|
466
|
-
*
|
480
|
+
* JRuby doesn't like some MPFR stuff, specifically sqrt tests fail.
|
481
|
+
* Rubinius in 1.9 mode fails a sprintf test in a minor way.
|
467
482
|
|
468
483
|
The below are inherited from Tomasz. I will go through these and see which are
|
469
484
|
still relevant, and which I understand.
|
470
485
|
|
471
486
|
* `mpz_fits_*` and 31 vs. 32 integer variables
|
472
487
|
* fix all sign issues (don't know what these are)
|
473
|
-
* `to_s` vs. `inspect`
|
474
488
|
* check if `mpz_addmul_ui` would optimize some statements
|
475
489
|
* some system that allows using denref and numref as normal ruby objects
|
476
490
|
* takeover code that replaces all `Bignums` with `GMP::Z`
|
Binary file
|
data/ext/extconf.rb
CHANGED
@@ -26,12 +26,23 @@ end
|
|
26
26
|
end
|
27
27
|
|
28
28
|
unless have_macro('SIZEOF_INTPTR_T')
|
29
|
-
check_sizeof('intptr_t')
|
29
|
+
check_sizeof('intptr_t', 'ruby.h')
|
30
30
|
end
|
31
31
|
|
32
|
+
# Need check for which ruby vm to see how to require various things
|
33
|
+
if (begin; Rubinius; rescue NameError; end) != nil
|
34
|
+
$CFLAGS += ' -DRUBY_ENGINE_RBX'
|
35
|
+
end
|
36
|
+
|
37
|
+
if (begin; JRuby; rescue NameError; end) != nil
|
38
|
+
$CFLAGS += ' -DRUBY_ENGINE_JRUBY'
|
39
|
+
end
|
40
|
+
|
41
|
+
|
32
42
|
$CFLAGS += ' -Wall -W -O6 -g'
|
33
43
|
if ok
|
34
44
|
create_makefile('gmp')
|
35
45
|
else
|
36
46
|
raise "Unable to build, correct above errors and rerun"
|
37
47
|
end
|
48
|
+
|
data/ext/gmpf.c
CHANGED
@@ -168,7 +168,7 @@ void mpf_set_value(MP_FLOAT *self_val, VALUE arg)
|
|
168
168
|
r_mpf_set_z(self_val, arg_val_z);
|
169
169
|
} else if (FLOAT_P(arg)) {
|
170
170
|
mpfr_set_d(self_val, NUM2DBL(arg), __gmp_default_rounding_mode);
|
171
|
-
} else if (
|
171
|
+
} else if (TYPE (arg) == T_FIXNUM) {
|
172
172
|
mpf_set_si(self_val, FIX2NUM(arg));
|
173
173
|
} else if (STRING_P(arg)) {
|
174
174
|
result = mpfr_set_str(self_val, StringValuePtr(arg), 10, __gmp_default_rounding_mode);
|
data/ext/gmpz.c
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
#include <gmpz.h>
|
2
2
|
#include <gmpq.h>
|
3
3
|
#include <gmpf.h>
|
4
|
+
|
5
|
+
#ifdef HAVE_RUBY_IO_H
|
4
6
|
#include <ruby/io.h>
|
7
|
+
#endif
|
5
8
|
|
6
9
|
/*
|
7
10
|
* Document-class: GMP::Z
|
@@ -717,17 +720,17 @@ void mpz_set_value(MP_INT *target, VALUE source, int base)
|
|
717
720
|
{
|
718
721
|
MP_INT *source_val;
|
719
722
|
|
720
|
-
if (GMPZ_P(source)) {
|
721
|
-
mpz_get_struct(source, source_val);
|
722
|
-
mpz_set(target, source_val);
|
723
|
-
} else if (
|
724
|
-
mpz_set_si(target, FIX2NUM(source));
|
725
|
-
} else if (STRING_P(source)) {
|
726
|
-
mpz_set_str(target, StringValuePtr(source), base);
|
727
|
-
} else if (BIGNUM_P(source)) {
|
728
|
-
mpz_set_bignum(target, source);
|
723
|
+
if (GMPZ_P (source)) {
|
724
|
+
mpz_get_struct (source, source_val);
|
725
|
+
mpz_set (target, source_val);
|
726
|
+
} else if (TYPE (source) == T_FIXNUM) {
|
727
|
+
mpz_set_si (target, FIX2NUM (source));
|
728
|
+
} else if (STRING_P (source)) {
|
729
|
+
mpz_set_str (target, StringValuePtr (source), base);
|
730
|
+
} else if (BIGNUM_P (source)) {
|
731
|
+
mpz_set_bignum (target, source);
|
729
732
|
} else {
|
730
|
-
rb_raise(rb_eTypeError, "Don't know how to convert %s into GMP_Z", rb_class2name(rb_class_of(source)));
|
733
|
+
rb_raise (rb_eTypeError, "Don't know how to convert %s into GMP_Z", rb_class2name (rb_class_of (source)));
|
731
734
|
}
|
732
735
|
}
|
733
736
|
|
@@ -788,12 +791,19 @@ VALUE r_gmpz_to_i(VALUE self)
|
|
788
791
|
char *str;
|
789
792
|
VALUE res;
|
790
793
|
|
791
|
-
mpz_get_struct(self, self_val);
|
792
|
-
if (mpz_fits_slong_p(self_val))
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
794
|
+
mpz_get_struct (self, self_val);
|
795
|
+
if (mpz_fits_slong_p (self_val)) {
|
796
|
+
#ifdef RUBY_ENGINE_JRUBY
|
797
|
+
/* JRuby has this as INT2FIX which is no good. Patch. */
|
798
|
+
return FIXABLE (mpz_get_si (self_val)) ? LONG2FIX (mpz_get_si (self_val)) : rb_ll2inum (mpz_get_si (self_val));
|
799
|
+
#else
|
800
|
+
return rb_int2inum (mpz_get_si (self_val));
|
801
|
+
#endif
|
802
|
+
}
|
803
|
+
|
804
|
+
str = mpz_get_str (NULL, 0, self_val);
|
805
|
+
res = rb_cstr2inum (str, 10);
|
806
|
+
free (str);
|
797
807
|
return res;
|
798
808
|
}
|
799
809
|
|
@@ -1126,41 +1136,41 @@ static VALUE r_gmpz_addmul_self(VALUE self, VALUE b, VALUE c)
|
|
1126
1136
|
MP_INT *self_val, *b_val, *c_val;
|
1127
1137
|
int free_b_val = 0;
|
1128
1138
|
|
1129
|
-
if (GMPZ_P(b)) {
|
1130
|
-
mpz_get_struct(b, b_val);
|
1131
|
-
} else if (FIXNUM_P(b)) {
|
1132
|
-
mpz_temp_alloc(b_val);
|
1133
|
-
mpz_init_set_si(b_val, FIX2NUM(b));
|
1139
|
+
if (GMPZ_P (b)) {
|
1140
|
+
mpz_get_struct (b, b_val);
|
1141
|
+
} else if (FIXNUM_P (b)) {
|
1142
|
+
mpz_temp_alloc (b_val);
|
1143
|
+
mpz_init_set_si (b_val, FIX2NUM (b));
|
1134
1144
|
free_b_val = 1;
|
1135
|
-
} else if (BIGNUM_P(b)) {
|
1136
|
-
mpz_temp_from_bignum(b_val, b);
|
1145
|
+
} else if (BIGNUM_P (b)) {
|
1146
|
+
mpz_temp_from_bignum (b_val, b);
|
1137
1147
|
free_b_val = 1;
|
1138
1148
|
} else {
|
1139
|
-
typeerror_as(ZXB, "addend");
|
1149
|
+
typeerror_as (ZXB, "addend");
|
1140
1150
|
}
|
1141
|
-
mpz_get_struct(self, self_val);
|
1151
|
+
mpz_get_struct (self, self_val);
|
1142
1152
|
|
1143
|
-
if (GMPZ_P(c)) {
|
1144
|
-
mpz_get_struct(c, c_val);
|
1145
|
-
mpz_addmul(self_val, b_val, c_val);
|
1146
|
-
} else if (
|
1147
|
-
if (FIX2NUM(c) < 0)
|
1153
|
+
if (GMPZ_P (c)) {
|
1154
|
+
mpz_get_struct (c, c_val);
|
1155
|
+
mpz_addmul (self_val, b_val, c_val);
|
1156
|
+
} else if (TYPE (c) == T_FIXNUM) {
|
1157
|
+
if (FIX2NUM (c) < 0)
|
1148
1158
|
{
|
1149
|
-
if (free_b_val) { mpz_temp_free(b_val); }
|
1150
|
-
rb_raise(rb_eRangeError, "multiplicand (Fixnum) must be nonnegative");
|
1159
|
+
if (free_b_val) { mpz_temp_free (b_val); }
|
1160
|
+
rb_raise (rb_eRangeError, "multiplicand (Fixnum) must be nonnegative");
|
1151
1161
|
}
|
1152
|
-
mpz_addmul_ui(self_val, b_val, FIX2NUM(c));
|
1153
|
-
} else if (BIGNUM_P(c)) {
|
1154
|
-
mpz_temp_from_bignum(c_val, c);
|
1155
|
-
mpz_addmul(self_val, b_val, c_val);
|
1156
|
-
mpz_temp_free(c_val);
|
1162
|
+
mpz_addmul_ui (self_val, b_val, FIX2NUM (c));
|
1163
|
+
} else if (BIGNUM_P (c)) {
|
1164
|
+
mpz_temp_from_bignum (c_val, c);
|
1165
|
+
mpz_addmul (self_val, b_val, c_val);
|
1166
|
+
mpz_temp_free (c_val);
|
1157
1167
|
} else {
|
1158
1168
|
if (free_b_val)
|
1159
|
-
mpz_temp_free(b_val);
|
1160
|
-
typeerror_as(ZXB, "multiplicand");
|
1169
|
+
mpz_temp_free (b_val);
|
1170
|
+
typeerror_as (ZXB, "multiplicand");
|
1161
1171
|
}
|
1162
1172
|
if (free_b_val)
|
1163
|
-
mpz_temp_free(b_val);
|
1173
|
+
mpz_temp_free (b_val);
|
1164
1174
|
return self;
|
1165
1175
|
}
|
1166
1176
|
|
@@ -1194,27 +1204,28 @@ static VALUE r_gmpz_submul_self(VALUE self, VALUE b, VALUE c)
|
|
1194
1204
|
}
|
1195
1205
|
mpz_get_struct(self, self_val);
|
1196
1206
|
|
1197
|
-
if (GMPZ_P(c)) {
|
1198
|
-
mpz_get_struct(c, c_val);
|
1199
|
-
mpz_submul(self_val, b_val, c_val);
|
1200
|
-
} else if (
|
1201
|
-
if (FIX2NUM(c) < 0)
|
1207
|
+
if (GMPZ_P (c)) {
|
1208
|
+
mpz_get_struct (c, c_val);
|
1209
|
+
mpz_submul (self_val, b_val, c_val);
|
1210
|
+
} else if (TYPE (c) == T_FIXNUM) {
|
1211
|
+
if (FIX2NUM (c) < 0)
|
1202
1212
|
{
|
1203
|
-
if (free_b_val) { mpz_temp_free(b_val); }
|
1204
|
-
rb_raise(rb_eRangeError, "multiplicand (Fixnum) must be nonnegative");
|
1213
|
+
if (free_b_val) { mpz_temp_free (b_val); }
|
1214
|
+
rb_raise (rb_eRangeError, "multiplicand (Fixnum) must be nonnegative");
|
1205
1215
|
}
|
1206
|
-
mpz_submul_ui(self_val, b_val, FIX2NUM(c));
|
1207
|
-
} else if (BIGNUM_P(c)) {
|
1208
|
-
mpz_temp_from_bignum(c_val, c);
|
1209
|
-
mpz_submul(self_val, b_val, c_val);
|
1210
|
-
mpz_temp_free(c_val);
|
1216
|
+
mpz_submul_ui (self_val, b_val, FIX2NUM (c));
|
1217
|
+
} else if (BIGNUM_P (c)) {
|
1218
|
+
mpz_temp_from_bignum (c_val, c);
|
1219
|
+
mpz_submul (self_val, b_val, c_val);
|
1220
|
+
mpz_temp_free (c_val);
|
1211
1221
|
} else {
|
1212
1222
|
if (free_b_val)
|
1213
|
-
mpz_temp_free(b_val);
|
1214
|
-
|
1223
|
+
mpz_temp_free (b_val);
|
1224
|
+
// rb_raise (rb_eTypeError, "base must be a Fixnum between 2 and 62, not a %s.", rb_class2name (rb_class_of (c)));
|
1225
|
+
typeerror_as (ZXB, "multiplicand");
|
1215
1226
|
}
|
1216
1227
|
if (free_b_val)
|
1217
|
-
mpz_temp_free(b_val);
|
1228
|
+
mpz_temp_free (b_val);
|
1218
1229
|
return self;
|
1219
1230
|
}
|
1220
1231
|
|
@@ -1504,22 +1515,22 @@ static VALUE r_gmpz_divisible(VALUE self, VALUE arg)
|
|
1504
1515
|
mpz_get_struct (self, self_val);
|
1505
1516
|
|
1506
1517
|
if (FIXNUM_P (arg) && FIX2NUM (arg) > 0) {
|
1507
|
-
mpz_temp_alloc(arg_val);
|
1508
|
-
mpz_init_set_ui(arg_val, FIX2NUM(arg));
|
1518
|
+
mpz_temp_alloc (arg_val);
|
1519
|
+
mpz_init_set_ui (arg_val, FIX2NUM (arg));
|
1509
1520
|
res = mpz_divisible_ui_p (self_val, FIX2NUM (arg));
|
1510
|
-
mpz_temp_free(arg_val);
|
1511
|
-
} else if (
|
1512
|
-
mpz_temp_alloc(arg_val);
|
1521
|
+
mpz_temp_free (arg_val);
|
1522
|
+
} else if (TYPE (arg) == T_FIXNUM) {
|
1523
|
+
mpz_temp_alloc (arg_val);
|
1513
1524
|
mpz_make_struct_init (arg, arg_val);
|
1514
|
-
mpz_init_set_si(arg_val, FIX2NUM(arg));
|
1525
|
+
mpz_init_set_si (arg_val, FIX2NUM (arg));
|
1515
1526
|
res = mpz_divisible_p (self_val, arg_val);
|
1516
|
-
mpz_temp_free(arg_val);
|
1527
|
+
mpz_temp_free (arg_val);
|
1517
1528
|
} else if (BIGNUM_P (arg)) {
|
1518
|
-
mpz_temp_from_bignum(arg_val, arg);
|
1529
|
+
mpz_temp_from_bignum (arg_val, arg);
|
1519
1530
|
res = mpz_divisible_p (self_val, arg_val);
|
1520
|
-
mpz_temp_free(arg_val);
|
1531
|
+
mpz_temp_free (arg_val);
|
1521
1532
|
} else if (GMPZ_P (arg)) {
|
1522
|
-
mpz_get_struct(arg, arg_val);
|
1533
|
+
mpz_get_struct (arg, arg_val);
|
1523
1534
|
res = mpz_divisible_p (self_val, arg_val);
|
1524
1535
|
} else {
|
1525
1536
|
typeerror_as (ZXB, "argument");
|
@@ -1705,6 +1716,45 @@ VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
|
|
1705
1716
|
*/
|
1706
1717
|
DEFUN_INT_F_UL(root,mpz_root,"root number")
|
1707
1718
|
|
1719
|
+
|
1720
|
+
/*
|
1721
|
+
* Document-method: rootrem
|
1722
|
+
*
|
1723
|
+
* call-seq:
|
1724
|
+
* a.rootrem(b)
|
1725
|
+
*
|
1726
|
+
* Returns the truncated integer part of the <i>b</i>th root of _a_, and the remainder, _a - root**b_.
|
1727
|
+
*/
|
1728
|
+
static VALUE r_gmpz_rootrem(VALUE self_val, VALUE exp_val)
|
1729
|
+
{
|
1730
|
+
MP_INT *self, *root, *rem;
|
1731
|
+
VALUE root_val, rem_val, ary;
|
1732
|
+
unsigned long exp;
|
1733
|
+
|
1734
|
+
if (FIXNUM_P(exp_val)) {
|
1735
|
+
if (FIX2NUM(exp_val) < 0)
|
1736
|
+
rb_raise(rb_eRangeError, "root number out of range");
|
1737
|
+
exp = FIX2NUM(exp_val);
|
1738
|
+
} else if (GMPZ_P(exp_val)) {
|
1739
|
+
mpz_get_struct(exp_val, root);
|
1740
|
+
if (!mpz_fits_ulong_p(root))
|
1741
|
+
rb_raise(rb_eRangeError, "root number out of range");
|
1742
|
+
exp = mpz_get_ui(root);
|
1743
|
+
if (exp_val == 0)
|
1744
|
+
rb_raise(rb_eRangeError, "root number out of range");
|
1745
|
+
} else {
|
1746
|
+
typeerror_as(ZX, "root number");
|
1747
|
+
}
|
1748
|
+
|
1749
|
+
mpz_make_struct_init(root_val, root);
|
1750
|
+
mpz_make_struct_init(rem_val, rem);
|
1751
|
+
mpz_get_struct(self_val, self);
|
1752
|
+
mpz_rootrem(root, rem, self, exp);
|
1753
|
+
|
1754
|
+
ary = rb_ary_new3 (2, root_val, rem_val);
|
1755
|
+
return ary;
|
1756
|
+
}
|
1757
|
+
|
1708
1758
|
/*
|
1709
1759
|
* Document-method: sqrt
|
1710
1760
|
*
|
@@ -1896,7 +1946,7 @@ VALUE r_gmpz_gcdext(VALUE self, VALUE arg)
|
|
1896
1946
|
mpz_make_struct_init (s, s_val);
|
1897
1947
|
mpz_make_struct_init (t, t_val);
|
1898
1948
|
mpz_temp_alloc (arg_val);
|
1899
|
-
mpz_init_set_ui (arg_val, FIX2NUM(arg));
|
1949
|
+
mpz_init_set_ui (arg_val, FIX2NUM (arg));
|
1900
1950
|
free_arg_val = 1;
|
1901
1951
|
mpz_gcdext (res_val, s_val, t_val, self_val, arg_val);
|
1902
1952
|
} else if (BIGNUM_P (arg)) {
|
@@ -2235,7 +2285,7 @@ DEFUN_INT_SINGLETON_UI(2fac, mpz_2fac_ui)
|
|
2235
2285
|
* Document-method: GMP::Z.mfac
|
2236
2286
|
*
|
2237
2287
|
* call-seq:
|
2238
|
-
* GMP::Z.mfac(n)
|
2288
|
+
* GMP::Z.mfac(n, m)
|
2239
2289
|
*
|
2240
2290
|
* Returns <i>n!^(m)</i>, the m-multi-factorial of _n_.
|
2241
2291
|
*
|
@@ -2262,7 +2312,7 @@ DEFUN_INT_SINGLETON_UIUI(mfac, mpz_mfac_uiui)
|
|
2262
2312
|
* call-seq:
|
2263
2313
|
* GMP::Z.primorial(n)
|
2264
2314
|
*
|
2265
|
-
* Returns the primorial _n_.
|
2315
|
+
* Returns the primorial of _n_.
|
2266
2316
|
*
|
2267
2317
|
* Examples:
|
2268
2318
|
* * GMP::Z.primorial(0) #=> 1
|
@@ -2747,6 +2797,7 @@ VALUE r_gmpz_getbit(VALUE self, VALUE bitnr)
|
|
2747
2797
|
*
|
2748
2798
|
* Return the number of bytes written, or if an error occurred, return 0.
|
2749
2799
|
*/
|
2800
|
+
#ifdef HAVE_RUBY_IO_H
|
2750
2801
|
VALUE r_gmpz_out_raw(VALUE self, VALUE stream)
|
2751
2802
|
{
|
2752
2803
|
MP_INT *self_val;
|
@@ -2783,6 +2834,7 @@ VALUE r_gmpzsg_inp_raw(VALUE klass, VALUE a_val, VALUE stream_val)
|
|
2783
2834
|
stream = rb_io_stdio_file (RFILE (stream_val)->fptr);
|
2784
2835
|
return INT2FIX (mpz_inp_raw (a, stream));
|
2785
2836
|
}
|
2837
|
+
#endif
|
2786
2838
|
|
2787
2839
|
|
2788
2840
|
/**********************************************************************
|
@@ -3037,12 +3089,13 @@ void init_gmpz()
|
|
3037
3089
|
rb_define_method(cGMP_Z, "powmod", r_gmpz_powm, 2);
|
3038
3090
|
|
3039
3091
|
// Integer Roots
|
3040
|
-
rb_define_method(cGMP_Z, "root", r_gmpz_root,
|
3041
|
-
rb_define_method(cGMP_Z, "
|
3092
|
+
rb_define_method(cGMP_Z, "root", r_gmpz_root, 1);
|
3093
|
+
rb_define_method(cGMP_Z, "rootrem", r_gmpz_rootrem, 1);
|
3094
|
+
rb_define_method(cGMP_Z, "sqrt", r_gmpz_sqrt, 0);
|
3042
3095
|
rb_define_method(cGMP_Z, "sqrt!", r_gmpz_sqrt_self, 0);
|
3043
|
-
rb_define_method(cGMP_Z, "sqrtrem", r_gmpz_sqrtrem,
|
3096
|
+
rb_define_method(cGMP_Z, "sqrtrem", r_gmpz_sqrtrem, 0);
|
3044
3097
|
rb_define_method(cGMP_Z, "square?", r_gmpz_is_square, 0);
|
3045
|
-
rb_define_method(cGMP_Z, "power?", r_gmpz_is_power,
|
3098
|
+
rb_define_method(cGMP_Z, "power?", r_gmpz_is_power, 0);
|
3046
3099
|
// Functional Mappings
|
3047
3100
|
rb_define_singleton_method(cGMP_Z, "sqrt", r_gmpzsg_sqrt, 2);
|
3048
3101
|
|
@@ -3103,9 +3156,11 @@ void init_gmpz()
|
|
3103
3156
|
rb_define_singleton_method(cGMP_Z, "com", r_gmpzsg_com, 2);
|
3104
3157
|
|
3105
3158
|
// I/O of Integers
|
3159
|
+
#ifdef HAVE_RUBY_IO_H
|
3106
3160
|
rb_define_method(cGMP_Z, "out_raw", r_gmpz_out_raw, 1);
|
3107
3161
|
// Functional Mapping
|
3108
3162
|
rb_define_singleton_method(cGMP_Z, "inp_raw", r_gmpzsg_inp_raw, 2);
|
3163
|
+
#endif
|
3109
3164
|
|
3110
3165
|
// Integer Import and Export
|
3111
3166
|
rb_define_singleton_method(cGMP_Z, "import", r_gmpzsg_import, -1);
|
data/ext/ruby_gmp.h
CHANGED
@@ -116,7 +116,7 @@ typedef __gmp_randstate_struct MP_RANDSTATE;
|
|
116
116
|
#endif
|
117
117
|
|
118
118
|
#ifdef FIXNUM_WIDTH /* RBX check */
|
119
|
-
#if (((8*SIZEOF_INTPTR_T) - TAG_FIXNUM_SHIFT -1)
|
119
|
+
#if (((8*SIZEOF_INTPTR_T) - TAG_FIXNUM_SHIFT -1) > 60) /* 64-bit */
|
120
120
|
#define FIX2NUM(x) FIX2LONG(x)
|
121
121
|
#else /* 32-bit */
|
122
122
|
#define FIX2NUM(x) FIX2INT(x)
|
File without changes
|
File without changes
|
File without changes
|
data/test/gmp_tprintf.rb
CHANGED
@@ -33,7 +33,7 @@ unless RUBY_VERSION =~ /^1.8/
|
|
33
33
|
assert(fmt.size < MAX_OUTPUT)
|
34
34
|
got = GMP.sprintf(fmt, *args)
|
35
35
|
|
36
|
-
assert_equal(want, got, "GMP.sprintf() generates correct output.")
|
36
|
+
assert_equal(want, got, "GMP.sprintf(#{fmt}, #{args.join(', ')}) generates correct output.")
|
37
37
|
end
|
38
38
|
|
39
39
|
def check_one(want, fmt, *args)
|
data/test/gmp_troot.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
2
|
+
|
3
|
+
class GMP_TRoot < Test::Unit::TestCase
|
4
|
+
RS = GMP::RandState.new(11213)
|
5
|
+
Reps = 500
|
6
|
+
|
7
|
+
def one_test(root1, x2, nth, i)
|
8
|
+
root2, rem2 = x2.rootrem(nth)
|
9
|
+
temp = root1 ** nth
|
10
|
+
temp2 = temp + rem2
|
11
|
+
|
12
|
+
assert_equal(root1, root2, "rootrem should produce the correct root for: #{x2}.rootrem(#{nth})")
|
13
|
+
assert_equal(x2, temp2, "rootrem should produce the correct remainder for: #{x2}.rootrem(#{nth})")
|
14
|
+
|
15
|
+
if nth > 1
|
16
|
+
assert_false((temp > 1 && ! temp.power?), "error in perfect_power?")
|
17
|
+
end
|
18
|
+
|
19
|
+
if nth <= 10_000 && x2 > 0
|
20
|
+
temp2 = root1 + 1
|
21
|
+
temp2 = temp2 ** nth
|
22
|
+
|
23
|
+
# Is square of (result + 1) <= argument?
|
24
|
+
assert_true(temp2 > x2, "square of (result + 1) should not be less than or equal to argument")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_root
|
29
|
+
bs = GMP::Z()
|
30
|
+
s2 = GMP::Z()
|
31
|
+
root1 = GMP::Z()
|
32
|
+
|
33
|
+
x2 = GMP::Z("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000002", 16)
|
34
|
+
root1 = x2.root(2)
|
35
|
+
one_test(root1, x2, 2, -1)
|
36
|
+
|
37
|
+
(0...Reps).each do |i|
|
38
|
+
size = RS.urandomb(32)
|
39
|
+
size = RS.urandomb((size % 17 + 2).to_i)
|
40
|
+
x2 = RS.rrandomb(size.to_i + 10)
|
41
|
+
|
42
|
+
size = RS.urandomb(15)
|
43
|
+
#nth = mpz_getlimbn (bs, 0) % mpz_sizeinbase (x2, 2) + 2;
|
44
|
+
nth = (size % 32).to_i % x2.size_in_bin + 2
|
45
|
+
root1 = x2.root(nth)
|
46
|
+
|
47
|
+
size = RS.urandomb(4)
|
48
|
+
|
49
|
+
# With 50% probability, set x2 near a perfect power.
|
50
|
+
one_test(root1, x2, nth, i)
|
51
|
+
if (nth & 1 != 0) && (size & 2 != 0)
|
52
|
+
x2.neg!
|
53
|
+
root1.neg!
|
54
|
+
one_test(root1, x2, nth, i)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/test/mpfr_tsqrt.rb
CHANGED
@@ -12,19 +12,19 @@ class MPFR_TSQRT < Test::Unit::TestCase
|
|
12
12
|
return 0 if exp < 0
|
13
13
|
f.to_s[2..(index_e-1)][0,exp]
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def check24(as, rnd_mode, qs)
|
17
17
|
q = GMP::F(as, 24)
|
18
18
|
q = q.sqrt(rnd_mode)
|
19
19
|
assert_equal(q, GMP::F(qs), "Sqrt of #{as} (prec 24) should be #{qs}.")
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def check_diverse(as, p, qs)
|
23
23
|
q = GMP::F(as, p)
|
24
24
|
q = q.sqrt
|
25
25
|
assert_equal(integer_component(q), qs)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def check_float
|
29
29
|
check24("70368760954880.0", GMP::GMP_RNDN, "8.388609e6")
|
30
30
|
check24("281474943156224.0", GMP::GMP_RNDN, "1.6777215e7")
|
@@ -36,7 +36,7 @@ class MPFR_TSQRT < Test::Unit::TestCase
|
|
36
36
|
check24("70368794509312.0", GMP::GMP_RNDN, "8.388611e6")
|
37
37
|
check24("281474876047360.0", GMP::GMP_RNDN, "1.6777213e7")
|
38
38
|
check24("91214552498176.0", GMP::GMP_RNDN, "9.550631e6")
|
39
|
-
|
39
|
+
|
40
40
|
check24("70368760954880.0", GMP::GMP_RNDZ, "8.388608e6")
|
41
41
|
check24("281474943156224.0", GMP::GMP_RNDZ, "1.6777214e7")
|
42
42
|
check24("70368777732096.0", GMP::GMP_RNDZ, "8.388609e6")
|
@@ -70,46 +70,46 @@ class MPFR_TSQRT < Test::Unit::TestCase
|
|
70
70
|
check24("281474876047360.0", GMP::GMP_RNDD, "1.6777212e7")
|
71
71
|
check24("91214552498176.0", GMP::GMP_RNDD, "9.550631e6")
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def special
|
75
75
|
x = GMP::F(0b1010000010100011011001010101010010001100001101011101110001011001 / 2, 64) # Ruby 0b does not support e,
|
76
76
|
y = x.sqrt(GMP::GMP_RNDN, 32) # ie 0b11e-2 = 0.75 doesnt work
|
77
77
|
#assert_equal(2405743844, y, "Error for n^2+n+1/2 with n=2405743843") # Pending
|
78
|
-
|
78
|
+
|
79
79
|
x = GMP::F(0b10100000101000110110010101010100100011000011010111011100010110001 / 4, 65)
|
80
80
|
y = x.sqrt(GMP::GMP_RNDN, 32)
|
81
81
|
#assert_equal(2405743844, y, "Error for n^2+n+1/4 with n=2405743843") # Pending
|
82
|
-
|
82
|
+
|
83
83
|
x = GMP::F(0b101000001010001101100101010101001000110000110101110111000101100011 / 8, 66)
|
84
84
|
y = x.sqrt(GMP::GMP_RNDN, 32)
|
85
85
|
#assert_equal(2405743844, y, "Error for n^2+n+1/4+1/8 with n=2405743843") # Pending
|
86
|
-
|
86
|
+
|
87
87
|
x = GMP::F(0b101000001010001101100101010101001000110000110101110111000101100001 / 8, 66)
|
88
88
|
y = x.sqrt(GMP::GMP_RNDN, 32)
|
89
89
|
assert_equal(2405743843, y, "Error for n^2+n+1/8 with n=2405743843")
|
90
|
-
|
90
|
+
|
91
91
|
#####
|
92
92
|
##### Inexact flag test. Not implemented.
|
93
|
-
|
93
|
+
|
94
94
|
#####
|
95
95
|
##### Test uses mpfr_nexttoinf. Not implemented.
|
96
|
-
|
96
|
+
|
97
97
|
# Not an accurate test at all. Reassigning z generates a new mpfr object.
|
98
98
|
x = GMP::F(1)
|
99
99
|
z = GMP::F(-1)
|
100
100
|
z = x.sqrt(GMP::GMP_RNDN)
|
101
|
-
|
101
|
+
|
102
102
|
#z = GMP::F(0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1, 160)
|
103
103
|
#x = z.sqrt
|
104
104
|
# z = x.sqrt
|
105
105
|
# x.prec = 53
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
def check_inexact(prec)
|
109
109
|
x = @rand_state.mpfr_urandomb(p)
|
110
|
-
|
110
|
+
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
def property1(p, rounding)
|
114
114
|
x = @rand_state.mpfr_urandomb(p)
|
115
115
|
y = @rand_state.mpfr_urandomb(p)
|
@@ -117,53 +117,53 @@ class MPFR_TSQRT < Test::Unit::TestCase
|
|
117
117
|
z = x / z.sqrt(rounding)
|
118
118
|
assert_between(-1, 1, z, "-1 <= x/sqrt(x^2+y^2) <= 1 should hold.")
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
def property2(p, rounding)
|
122
122
|
x = @rand_state.mpfr_urandomb(p)
|
123
123
|
y = (x * x).sqrt(rounding)
|
124
124
|
assert_true(x == y, "sqrt(#{x.to_s}^2) should be #{x.to_s}, but is #{y.to_s} (rounding: #{GMP::F.default_rounding_mode.inspect}, prec: #{p.to_s}).")
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
def check3(as, rounding, qs)
|
128
128
|
q = GMP::F(as, 53)
|
129
129
|
q = q.sqrt(rounding)
|
130
130
|
assert_equal(GMP::F(qs), q, "Sqrt of -0.0 should be something like 0.0.")
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
def check4(as, rounding, qs)
|
134
134
|
q = GMP::F(as, 53)
|
135
135
|
q = q.sqrt(rounding)
|
136
136
|
assert_equal(q, GMP::F(qs, GMP::F.default_prec, 16), "Sqrt of #{as} should be #{qs}.")
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
def test_prec
|
140
140
|
(GMP::MPFR_PREC_MIN..128).each do |p|
|
141
141
|
property1(p, GMP::GMP_RNDN)
|
142
142
|
property1(p, GMP::GMP_RNDU)
|
143
143
|
property2(p, GMP::GMP_RNDN)
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
check_diverse("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328",
|
147
147
|
160,
|
148
148
|
"796887792767063979679855997149887366668464780637")
|
149
149
|
special
|
150
150
|
#check_nan
|
151
|
-
|
151
|
+
|
152
152
|
(2...200).each do |p|
|
153
153
|
200.times do
|
154
154
|
#check_inexact p
|
155
155
|
end
|
156
156
|
end
|
157
157
|
check_float
|
158
|
-
|
158
|
+
|
159
159
|
check3("-0.0", GMP::GMP_RNDN, "0.0")
|
160
|
-
|
160
|
+
|
161
161
|
check4("6.37983013646045901440e+32", GMP::GMP_RNDN, "5.9bc5036d09e0c@13")
|
162
162
|
check4("1.0", GMP::GMP_RNDN, "1")
|
163
163
|
check4("1.0", GMP::GMP_RNDZ, "1")
|
164
164
|
check4("3.725290298461914062500000e-9", GMP::GMP_RNDN, "4@-4")
|
165
165
|
check4("3.725290298461914062500000e-9", GMP::GMP_RNDZ, "4@-4")
|
166
|
-
|
166
|
+
|
167
167
|
check4("1190456976439861.0", GMP::GMP_RNDZ, "2.0e7957873529a@6")
|
168
168
|
check4("1219027943874417664.0", GMP::GMP_RNDZ, "4.1cf2af0e6a534@7")
|
169
169
|
# the following examples are bugs in Cygnus compiler/system, found by
|
data/test/tc_z_io.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
|
+
if (RUBY_DESCRIPTION =~ /rubinius/i and RUBY_VERSION =~ /^1.8/) ||
|
5
|
+
(RUBY_DESCRIPTION =~ /jruby/i)
|
6
|
+
# Sorry charlie
|
7
|
+
else
|
4
8
|
class TC_Z_IO < Test::Unit::TestCase
|
5
9
|
def setup
|
6
10
|
@two_pow_100 = GMP::Z.pow(GMP::Z(2), 100)
|
@@ -48,3 +52,4 @@ class TC_Z_IO < Test::Unit::TestCase
|
|
48
52
|
FileUtils.rm('test_io_raw')
|
49
53
|
end
|
50
54
|
end
|
55
|
+
end
|
data/test/unit_tests.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.31
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-02-06 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: gmp - providing Ruby bindings to the GMP library.
|
16
16
|
email:
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- test/gmp_tgcd.rb
|
41
41
|
- test/gmp_tlcm.rb
|
42
42
|
- test/gmp_tprintf.rb
|
43
|
+
- test/gmp_troot.rb
|
43
44
|
- test/mpfr_tcbrt.rb
|
44
45
|
- test/mpfr_tconst_euler.rb
|
45
46
|
- test/mpfr_tisnan.rb
|
@@ -89,6 +90,7 @@ files:
|
|
89
90
|
- test/README
|
90
91
|
- test/test_unit/assertions.rb
|
91
92
|
- benchmark/benchmark-results-5.0.5_1.9.3_0.6.7.ods
|
93
|
+
- benchmark/benchmark-results-5.1.0_0.6.19.ods
|
92
94
|
- CHANGELOG
|
93
95
|
- INSTALL
|
94
96
|
- README.html
|
@@ -96,9 +98,9 @@ files:
|
|
96
98
|
- manual.pdf
|
97
99
|
- manual.tex
|
98
100
|
- FEATURES.html
|
99
|
-
- performance.md
|
100
|
-
- performance.html
|
101
|
-
- performance.pdf
|
101
|
+
- performance.2012.md
|
102
|
+
- performance.2012.html
|
103
|
+
- performance.2012.pdf
|
102
104
|
homepage: http://github.com/srawlins/gmp
|
103
105
|
licenses: []
|
104
106
|
post_install_message:
|