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 CHANGED
@@ -1,3 +1,6 @@
1
+ 0.6.31:
2
+ * Added GMP::Z#rootrem and tests
3
+
1
4
  0.6.19:
2
5
  * Added GMP::Z#congruent? and tests
3
6
  * Added GMP::Z#export and GMP::Z.import and _minimal_ tests
@@ -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="4">Mac OS X 10.6.8 on x86_64 (64-bit)</td>
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
  &gt;&gt; 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 #=&gt; 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 badasses: <a href="http://rubydoc.info/gems/gmp/frames">YARDoc</a>.</li>
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
- <ul>
437
- <li>Don&#39;t call <code>GMP::RandState(:lc_2exp_size)</code>. Give a 2nd arg.</li>
438
- <li>Don&#39;t use multiple assignment (<code>a = b = GMP::Z(0)</code>) with functional mappings.</li>
439
- <li>JRuby has some interesting bugs and flickering tests. GMP::Z(GMP::GMP<em>NUMB</em>MAX) for example, blows up.</li>
440
- </ul>
441
+ <p>Don&#39;t call <code>GMP::RandState(:lc_2exp_size)</code>. Give a 2nd arg.
442
+ Don&#39;t use multiple assignment (<code>a = b = GMP::Z(0)</code>) with functional mappings:</p>
443
+
444
+ <p><code>ruby
445
+ &gt;&gt; a = b = GMP::Z(0)
446
+ =&gt; 0
447
+ &gt;&gt; GMP::Z.mul(a, GMP::Z(2), GMP::Z(3))
448
+ =&gt; nil
449
+ &gt;&gt; a
450
+ =&gt; 6
451
+ &gt;&gt; b
452
+ =&gt; 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>#congruent?</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>
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>
@@ -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
- * Don't call `GMP::RandState(:lc_2exp_size)`. Give a 2nd arg.
436
- * Don't use multiple assignment (`a = b = GMP::Z(0)`) with functional mappings.
437
- * JRuby has some interesting bugs and flickering tests. GMP::Z(GMP::GMP_NUMB_MAX) for example, blows up.
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`, `#rootrem`, `#kronecker`, `#bin`, `#fib2`, `#lucnum`, `#lucnum2`, `#combit`, `#fits_x?`
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
- * benchmark different orderings of type checks
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`
@@ -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 (FIXNUM_P(arg)) {
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 (FIXNUM_P(source)) {
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
- return rb_int2inum(mpz_get_si(self_val));
794
- str = mpz_get_str(NULL, 0, self_val);
795
- res = rb_cstr2inum(str, 10);
796
- free(str);
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 (FIXNUM_P(c)) {
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 (FIXNUM_P(c)) {
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
- typeerror_as(ZXB, "multiplicand");
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 (FIXNUM_P (arg)) {
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, 1);
3041
- rb_define_method(cGMP_Z, "sqrt", r_gmpz_sqrt, 0);
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, 0);
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, 0);
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);
@@ -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) == 63) /* 64-bit */
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
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -37,6 +37,7 @@ require './gmp_tcong'
37
37
  require './gmp_tgcd'
38
38
  require './gmp_tlcm'
39
39
  require './gmp_tprintf'
40
+ require './gmp_troot'
40
41
 
41
42
  begin
42
43
  GMP::MPFR_VERSION
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.19
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: 2012-12-31 00:00:00.000000000 Z
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: