gmp 0.6.19 → 0.6.31
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 +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:
|