gmp 0.4.7 → 0.5.3

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.
Files changed (53) hide show
  1. data/CHANGELOG +31 -0
  2. data/README.rdoc +16 -8
  3. data/benchmark/multiply +1 -1
  4. data/benchmark/multiply.gc +57 -0
  5. data/benchmark/pi +126 -0
  6. data/benchmark/srb.sh +21 -0
  7. data/ext/extconf.rb +3 -0
  8. data/ext/gmp.c +16 -7
  9. data/ext/gmpbench_timing.c +1 -1
  10. data/ext/gmpf.c +445 -104
  11. data/ext/gmpq.c +25 -17
  12. data/ext/gmpz.c +232 -120
  13. data/ext/mprnd.c +23 -5
  14. data/ext/ruby_gmp.h +75 -9
  15. data/lib/gmp.rb +9 -0
  16. data/manual.pdf +0 -0
  17. data/manual.tex +494 -60
  18. data/test/README +1 -0
  19. data/test/mpfr_tcbrt.rb +95 -0
  20. data/test/mpfr_tisnan.rb +70 -0
  21. data/test/mpfr_trec_sqrt.rb +62 -0
  22. data/test/mpfr_tsqrt.rb +142 -6
  23. data/test/tc_cmp.rb +4 -4
  24. data/test/tc_constants.rb +10 -0
  25. data/test/tc_division.rb +13 -2
  26. data/test/tc_f_arithmetics_coersion.rb +2 -2
  27. data/test/tc_f_precision.rb +4 -3
  28. data/test/tc_fib_fac_nextprime.rb +2 -2
  29. data/test/tc_floor_ceil_truncate.rb +2 -2
  30. data/test/tc_hashes.rb +0 -2
  31. data/test/tc_logical_roots.rb +1 -3
  32. data/test/tc_mpfr_constants.rb +11 -0
  33. data/test/tc_mpfr_functions.rb +22 -9
  34. data/test/tc_mpfr_random.rb +1 -3
  35. data/test/tc_mpfr_rounding.rb +10 -7
  36. data/test/tc_q.rb +1 -3
  37. data/test/tc_q_basic.rb +3 -5
  38. data/test/tc_random.rb +1 -3
  39. data/test/tc_sgn_neg_abs.rb +1 -3
  40. data/test/tc_swap.rb +1 -3
  41. data/test/tc_z.rb +3 -3
  42. data/test/tc_z_addmul.rb +92 -0
  43. data/test/tc_z_basic.rb +6 -8
  44. data/test/tc_z_exponentiation.rb +1 -3
  45. data/test/tc_z_gcd_lcm_invert.rb +1 -3
  46. data/test/tc_z_jac_leg_rem.rb +1 -3
  47. data/test/tc_z_logic.rb +2 -2
  48. data/test/tc_z_shifts_last_bits.rb +2 -2
  49. data/test/tc_z_to_d_to_i.rb +2 -2
  50. data/test/test_helper.rb +1 -1
  51. data/test/test_unit/assertions.rb +31 -0
  52. data/test/unit_tests.rb +33 -27
  53. metadata +31 -6
data/ext/gmpq.c CHANGED
@@ -156,8 +156,8 @@ VALUE r_gmpq_to_s(VALUE self)
156
156
  MP_INT *self_val_num, *self_val_den;
157
157
  char *str;
158
158
  VALUE res;
159
- int sizeinbase;
160
- int offset;
159
+ size_t sizeinbase;
160
+ size_t offset;
161
161
 
162
162
  //Data_Get_Struct (self, MP_RAT, self_val);
163
163
  mpq_get_struct(self, self_val)
@@ -222,10 +222,14 @@ VALUE r_gmpq_add(VALUE self, VALUE arg)
222
222
  } else if (FIXNUM_P(arg)) {
223
223
  res_val_num = mpq_numref(res_val);
224
224
  mpz_set(mpq_denref(res_val), mpq_denref(self_val));
225
- mpz_mul_si(res_val_num, mpq_denref(self_val), FIX2INT(arg));
225
+ mpz_mul_si(res_val_num, mpq_denref(self_val), FIX2NUM(arg));
226
226
  mpz_add(res_val_num, res_val_num, mpq_numref(self_val));
227
227
  } else if (GMPF_P(arg)) {
228
+ #ifndef MPFR
228
229
  return r_gmpf_add(arg,self);
230
+ #else
231
+ return rb_funcall(arg, rb_intern("+"), 1, self);
232
+ #endif
229
233
  } else if (BIGNUM_P(arg)) {
230
234
  res_val_num = mpq_numref(res_val);
231
235
  mpz_set(mpq_denref(res_val), mpq_denref(self_val));
@@ -255,7 +259,7 @@ VALUE r_gmpq_sub(VALUE self, VALUE arg)
255
259
  MP_INT *arg_val_z, *res_val_num;
256
260
  MP_FLOAT *arg_val_f, *res_val_f;
257
261
  VALUE res;
258
- unsigned int prec;
262
+ mpfr_prec_t prec;
259
263
 
260
264
  mpq_get_struct(self, self_val);
261
265
  mpq_make_struct_init(res, res_val);
@@ -273,7 +277,7 @@ VALUE r_gmpq_sub(VALUE self, VALUE arg)
273
277
  } else if (FIXNUM_P(arg)) {
274
278
  res_val_num = mpq_numref(res_val);
275
279
  mpz_set (mpq_denref(res_val), mpq_denref(self_val));
276
- mpz_mul_si (res_val_num, mpq_denref(self_val), -FIX2INT(arg));
280
+ mpz_mul_si (res_val_num, mpq_denref(self_val), -FIX2NUM(arg));
277
281
  mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
278
282
  } else if (GMPF_P(arg)) {
279
283
  mpf_get_struct_prec (arg, arg_val_f, prec);
@@ -329,24 +333,28 @@ VALUE r_gmpq_mul(VALUE self, VALUE arg)
329
333
  mpz_temp_free(tmp_z);
330
334
  } else if (FIXNUM_P(arg)) {
331
335
  #if GMP >= 4
332
- if (FIX2INT(arg) > 0) {
333
- tmp_ui = mpz_gcd_ui(0, mpq_denref(self_val), FIX2INT(arg));
334
- } else if (FIX2INT(arg) < 0) {
335
- tmp_ui = mpz_gcd_ui(0, mpq_denref(self_val), -FIX2INT(arg));
336
+ if (FIX2NUM(arg) > 0) {
337
+ tmp_ui = mpz_gcd_ui(0, mpq_denref(self_val), FIX2NUM(arg));
338
+ } else if (FIX2NUM(arg) < 0) {
339
+ tmp_ui = mpz_gcd_ui(0, mpq_denref(self_val), -FIX2NUM(arg));
336
340
  } else {
337
341
  mpz_set_ui(mpq_numref(res_val), 0);
338
342
  mpz_set_ui(mpq_denref(res_val), 1);
339
343
  return res;
340
344
  }
341
345
  mpz_divexact_ui(mpq_denref(res_val), mpq_denref(self_val), tmp_ui);
342
- mpz_mul_ui(mpq_numref(res_val), mpq_numref(self_val), FIX2INT(arg)/tmp_ui);
346
+ mpz_mul_ui(mpq_numref(res_val), mpq_numref(self_val), FIX2NUM(arg)/tmp_ui);
343
347
  #else
344
348
  mpz_set(mpq_denref(res_val), mpq_denref(self_val));
345
- mpz_mul_si(mpq_numref(res_val), mpq_numref(self_val), FIX2INT(arg));
349
+ mpz_mul_si(mpq_numref(res_val), mpq_numref(self_val), FIX2NUM(arg));
346
350
  mpq_canonicalize(res_val);
347
351
  #endif
348
352
  } else if (GMPF_P(arg)) {
353
+ #ifndef MPFR
349
354
  return r_gmpf_mul(arg, self);
355
+ #else
356
+ return rb_funcall(arg, rb_intern("*"), 1, self);
357
+ #endif
350
358
  } else if (BIGNUM_P(arg)) {
351
359
  mpz_temp_alloc(tmp_z);
352
360
  mpz_set_bignum(tmp_z, arg);
@@ -397,15 +405,15 @@ VALUE r_gmpq_div(VALUE self, VALUE arg)
397
405
  mpz_mul(mpq_denref(res_val), mpq_denref(res_val), mpq_denref(self_val));
398
406
  mpz_temp_free(tmp_z);
399
407
  } else if (FIXNUM_P(arg)) {
400
- if (FIX2INT(arg) == 0)
408
+ if (FIX2NUM(arg) == 0)
401
409
  rb_raise(rb_eZeroDivError, "divided by 0");
402
- if (FIX2INT(arg) > 0) {
403
- tmp_ui = mpz_gcd_ui(0, mpq_numref(self_val), FIX2INT(arg));
410
+ if (FIX2NUM(arg) > 0) {
411
+ tmp_ui = mpz_gcd_ui(0, mpq_numref(self_val), FIX2NUM(arg));
404
412
  } else {
405
- tmp_ui = mpz_gcd_ui(0, mpq_numref(self_val), -FIX2INT(arg));
413
+ tmp_ui = mpz_gcd_ui(0, mpq_numref(self_val), -FIX2NUM(arg));
406
414
  }
407
415
  mpz_divexact_ui(mpq_numref(res_val), mpq_numref(self_val), tmp_ui);
408
- mpz_mul_ui(mpq_denref(res_val), mpq_denref(self_val), FIX2INT(arg)/tmp_ui);
416
+ mpz_mul_ui(mpq_denref(res_val), mpq_denref(self_val), FIX2NUM(arg)/tmp_ui);
409
417
  } else if (GMPF_P(arg)) {
410
418
  mpf_get_struct_prec(arg, arg_val_f, prec);
411
419
  mpf_make_struct_init(res, res_val_f, prec);
@@ -557,7 +565,7 @@ int mpq_cmp_value(MP_RAT *OP, VALUE arg)
557
565
  } else if (FIXNUM_P(arg)) {
558
566
  mpz_temp_alloc(tmp_z);
559
567
  mpz_init(tmp_z);
560
- mpz_mul_si(tmp_z, mpq_denref(OP), FIX2INT(arg));
568
+ mpz_mul_si(tmp_z, mpq_denref(OP), FIX2NUM(arg));
561
569
  res = mpz_cmp(mpq_numref(OP), tmp_z);
562
570
  mpz_temp_free(tmp_z);
563
571
  return res;
data/ext/gmpz.c CHANGED
@@ -19,10 +19,17 @@
19
19
  * to_i r_gmpz_to_i mpz_get_i
20
20
  * to_s r_gmpz_to_s mpz_get_s
21
21
  * + r_gmpz_add mpz_add
22
+ * \------------------------ mpz_add_ui
22
23
  * add! r_gmpz_add_self mpz_add
24
+ * \----------------------------- mpz_add_ui
23
25
  * - r_gmpz_sub mpz_sub
26
+ * \------------------------ mpz_sub_ui
24
27
  * sub! r_gmpz_sub_self mpz_sub
28
+ * \----------------------------- mpz_sub_ui
25
29
  * * r_gmpz_mul mpz_mul
30
+ * \------------------------ mpz_mul_si
31
+ * addmul! r_gmpz_addmul_self mpz_addmul
32
+ * \-------------------------------- mpz_addmul_ui
26
33
  * / r_gmpz_div ...
27
34
  * tdiv r_gmpz_tdiv mpz_tdiv_q
28
35
  * tmod r_gmpz_tmod mpz_tdiv_r
@@ -81,12 +88,19 @@
81
88
  * odd? r_gmpz_is_odd mpz_odd
82
89
  * sizeinbase r_gmpz_sizeinbase mpz_sizeinbase
83
90
  * size_in_bin r_gmpz_size_in_bin mpz_sizeinbits
91
+ * size r_gmpz_size mpz_size
84
92
  */
85
93
 
86
94
  /**********************************************************************
87
95
  * Macros *
88
96
  **********************************************************************/
89
97
 
98
+ /*
99
+ * DEFUN_INT2INT defines two functions. The first takes a GMP::Z as
100
+ * self, calls mpz_fname on the contained mpz_t, whose arguments are
101
+ * exactly (0) the return argument and (1) self. The second is the same
102
+ * destructive method.
103
+ */
90
104
  #define DEFUN_INT2INT(fname,mpz_fname) \
91
105
  static VALUE r_gmpz_##fname(VALUE self) \
92
106
  { \
@@ -106,6 +120,12 @@ static VALUE r_gmpz_##fname##_self(VALUE self) \
106
120
  return self; \
107
121
  }
108
122
 
123
+ /*
124
+ * DEFUNN_INT_F_UL defines a function that takes a GMP::Z as self,
125
+ * and a FIXNUM or GMP::Z as exp. It calls mpz_fname on the contained
126
+ * mpz_t, whose arguments are (0) the return argument, (1) self, and
127
+ * (2) exp_value. exp must fit into a ulong.
128
+ */
109
129
  #define DEFUN_INT_F_UL(fname,mpz_fname,argname) \
110
130
  static VALUE r_gmpz_##fname(VALUE self, VALUE exp) \
111
131
  { \
@@ -114,9 +134,9 @@ static VALUE r_gmpz_##fname(VALUE self, VALUE exp) \
114
134
  unsigned long exp_val; \
115
135
  \
116
136
  if (FIXNUM_P(exp)) { \
117
- if (FIX2INT(exp) < 0) \
137
+ if (FIX2NUM(exp) < 0) \
118
138
  rb_raise(rb_eRangeError, argname " out of range"); \
119
- exp_val = FIX2INT(exp); \
139
+ exp_val = FIX2NUM(exp); \
120
140
  } else if (GMPZ_P(exp)) { \
121
141
  mpz_get_struct(exp, res_val); \
122
142
  if (!mpz_fits_ulong_p(res_val)) \
@@ -148,7 +168,7 @@ static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
148
168
  { \
149
169
  MP_INT *self_val, *arg_val, *res_val; \
150
170
  VALUE res; \
151
- int arg_val_i; \
171
+ long arg_val_i; \
152
172
  \
153
173
  mpz_get_struct(self, self_val); \
154
174
  mpz_make_struct_init(res, res_val); \
@@ -159,7 +179,7 @@ static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
159
179
  rb_raise (rb_eZeroDivError, "divided by 0"); \
160
180
  gmp_fname (res_val, self_val, arg_val); \
161
181
  } else if (FIXNUM_P(arg)) { \
162
- arg_val_i = FIX2INT(arg); \
182
+ arg_val_i = FIX2NUM(arg); \
163
183
  if (arg_val_i > 0) { \
164
184
  gmp_fname##_ui (res_val, self_val, arg_val_i); \
165
185
  } else if (arg_val_i == 0) { \
@@ -185,50 +205,50 @@ static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
185
205
  MP_INT *self_val, *arg_val, *res_val; \
186
206
  VALUE res; \
187
207
  \
188
- mpz_get_struct(self, self_val); \
208
+ mpz_get_struct (self, self_val); \
189
209
  \
190
- mpz_make_struct(res, res_val); \
191
- if (GMPZ_P(arg)) { \
192
- mpz_get_struct(arg,arg_val); \
193
- mpz_init(res_val); \
194
- mpz_fname(res_val, self_val, arg_val); \
195
- } else if (FIXNUM_P(arg)) { \
196
- mpz_init_set_si(res_val, FIX2INT(arg)); \
197
- mpz_fname(res_val, self_val, res_val); \
198
- } else if (BIGNUM_P(arg)) { \
199
- mpz_init(res_val); \
200
- mpz_set_bignum(res_val, arg); \
201
- mpz_fname(res_val, self_val, res_val); \
210
+ mpz_make_struct (res, res_val); \
211
+ if (GMPZ_P (arg)) { \
212
+ mpz_get_struct (arg,arg_val); \
213
+ mpz_init (res_val); \
214
+ mpz_fname (res_val, self_val, arg_val); \
215
+ } else if (FIXNUM_P (arg)) { \
216
+ mpz_init_set_si (res_val, FIX2NUM (arg)); \
217
+ mpz_fname (res_val, self_val, res_val); \
218
+ } else if (BIGNUM_P (arg)) { \
219
+ mpz_init (res_val); \
220
+ mpz_set_bignum (res_val, arg); \
221
+ mpz_fname (res_val, self_val, res_val); \
202
222
  } else { \
203
- typeerror(ZXB); \
223
+ typeerror (ZXB); \
204
224
  } \
205
225
  return res; \
206
226
  }
207
227
 
208
- #define DEFUN_INT_SINGLETON_UI(fname,mpz_fname) \
209
- static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg) \
210
- { \
211
- MP_INT *arg_val_z, *res_val; \
212
- unsigned long arg_val_ul; \
213
- VALUE res; \
214
- \
215
- (void)klass; \
216
- \
217
- if (FIXNUM_P(arg)) { \
218
- arg_val_ul = FIX2INT (arg); \
219
- } else if (GMPZ_P(arg)) { \
220
- mpz_get_struct(arg, arg_val_z); \
221
- if (!mpz_fits_ulong_p (arg_val_z)) \
222
- rb_raise(rb_eRangeError, "argument out of range"); \
223
- arg_val_ul = mpz_get_ui(arg_val_z); \
224
- if (arg_val_ul == 0) \
225
- rb_raise(rb_eRangeError, "argument out of range"); \
226
- } else { \
227
- typeerror_as(ZX, "argument"); \
228
- } \
229
- mpz_make_struct_init(res, res_val); \
230
- mpz_fname(res_val, arg_val_ul); \
231
- return res; \
228
+ #define DEFUN_INT_SINGLETON_UI(fname,mpz_fname) \
229
+ static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg) \
230
+ { \
231
+ MP_INT *arg_val_z, *res_val; \
232
+ unsigned long arg_val_ul; \
233
+ VALUE res; \
234
+ \
235
+ (void)klass; \
236
+ \
237
+ if (FIXNUM_P (arg)) { \
238
+ arg_val_ul = FIX2NUM (arg); \
239
+ } else if (GMPZ_P (arg)) { \
240
+ mpz_get_struct (arg, arg_val_z); \
241
+ if (!mpz_fits_ulong_p (arg_val_z)) \
242
+ rb_raise (rb_eRangeError, "argument out of range"); \
243
+ arg_val_ul = mpz_get_ui (arg_val_z); \
244
+ if (arg_val_ul == 0) \
245
+ rb_raise (rb_eRangeError, "argument out of range"); \
246
+ } else { \
247
+ typeerror_as (ZX, "argument"); \
248
+ } \
249
+ mpz_make_struct_init (res, res_val); \
250
+ mpz_fname (res_val, arg_val_ul); \
251
+ return res; \
232
252
  }
233
253
 
234
254
  /**********************************************************************
@@ -289,9 +309,9 @@ void mpz_set_value(MP_INT *target, VALUE source)
289
309
  mpz_get_struct(source, source_val);
290
310
  mpz_set(target, source_val);
291
311
  } else if (FIXNUM_P(source)) {
292
- mpz_set_si(target, NUM2INT(source));
312
+ mpz_set_si(target, FIX2NUM(source));
293
313
  } else if (STRING_P(source)) {
294
- mpz_set_str(target, STR2CSTR(source), 0);
314
+ mpz_set_str(target, StringValuePtr(source), 0);
295
315
  } else if (BIGNUM_P(source)) {
296
316
  mpz_set_bignum(target, source);
297
317
  } else {
@@ -482,14 +502,18 @@ VALUE r_gmpz_add(VALUE self, VALUE arg)
482
502
  mpz_add(res_val, self_val, arg_val);
483
503
  } else if (FIXNUM_P(arg)) {
484
504
  mpz_make_struct_init(res, res_val);
485
- if (FIX2INT(arg) > 0)
486
- mpz_add_ui(res_val, self_val, FIX2INT(arg));
505
+ if (FIX2NUM(arg) > 0)
506
+ mpz_add_ui(res_val, self_val, FIX2NUM(arg));
487
507
  else
488
- mpz_sub_ui(res_val, self_val, -FIX2INT(arg));
508
+ mpz_sub_ui(res_val, self_val, -FIX2NUM(arg));
489
509
  } else if (GMPQ_P(arg)) {
490
510
  return r_gmpq_add(arg, self);
491
511
  } else if (GMPF_P(arg)) {
512
+ #ifndef MPFR
492
513
  return r_gmpf_add(arg, self);
514
+ #else
515
+ return rb_funcall(arg, rb_intern("+"), 1, self);
516
+ #endif
493
517
  } else if (BIGNUM_P(arg)) {
494
518
  mpz_make_struct_init(res, res_val);
495
519
  mpz_init(res_val);
@@ -523,10 +547,10 @@ VALUE r_gmpz_add_self(VALUE self, VALUE arg)
523
547
  mpz_get_struct(arg,arg_val);
524
548
  mpz_add(self_val, self_val, arg_val);
525
549
  } else if (FIXNUM_P(arg)) {
526
- if (FIX2INT(arg) > 0)
527
- mpz_add_ui(self_val, self_val, FIX2INT(arg));
550
+ if (FIX2NUM(arg) > 0)
551
+ mpz_add_ui(self_val, self_val, FIX2NUM(arg));
528
552
  else
529
- mpz_sub_ui(self_val, self_val, -FIX2INT(arg));
553
+ mpz_sub_ui(self_val, self_val, -FIX2NUM(arg));
530
554
  } else if (BIGNUM_P(arg)) {
531
555
  mpz_temp_from_bignum(arg_val, arg);
532
556
  mpz_add(self_val, self_val, arg_val);
@@ -564,10 +588,10 @@ VALUE r_gmpz_sub(VALUE self, VALUE arg)
564
588
  mpz_sub (res_val, self_val, arg_val);
565
589
  } else if (FIXNUM_P(arg)) {
566
590
  mpz_make_struct_init(res, res_val);
567
- if (FIX2INT(arg) > 0)
568
- mpz_sub_ui (res_val, self_val, FIX2INT(arg));
591
+ if (FIX2NUM(arg) > 0)
592
+ mpz_sub_ui (res_val, self_val, FIX2NUM(arg));
569
593
  else
570
- mpz_add_ui (res_val, self_val, -FIX2INT(arg));
594
+ mpz_add_ui (res_val, self_val, -FIX2NUM(arg));
571
595
  } else if (GMPQ_P(arg)) {
572
596
  mpq_make_struct_init(res, res_val_q);
573
597
  mpq_get_struct(arg,arg_val_q);
@@ -611,10 +635,10 @@ VALUE r_gmpz_sub_self(VALUE self, VALUE arg)
611
635
  mpz_get_struct(arg, arg_val);
612
636
  mpz_sub (self_val, self_val, arg_val);
613
637
  } else if (FIXNUM_P(arg)) {
614
- if (FIX2INT(arg) > 0)
615
- mpz_sub_ui (self_val, self_val, FIX2INT(arg));
638
+ if (FIX2NUM(arg) > 0)
639
+ mpz_sub_ui (self_val, self_val, FIX2NUM(arg));
616
640
  else
617
- mpz_add_ui (self_val, self_val, -FIX2INT(arg));
641
+ mpz_add_ui (self_val, self_val, -FIX2NUM(arg));
618
642
  } else if (BIGNUM_P(arg)) {
619
643
  mpz_temp_from_bignum(arg_val, arg);
620
644
  mpz_sub (self_val, self_val, arg_val);
@@ -649,11 +673,15 @@ VALUE r_gmpz_mul(VALUE self, VALUE arg)
649
673
  mpz_mul(res_val, self_val, arg_val);
650
674
  } else if (FIXNUM_P(arg)) {
651
675
  mpz_make_struct_init(res, res_val);
652
- mpz_mul_si(res_val, self_val, FIX2INT(arg));
676
+ mpz_mul_si(res_val, self_val, FIX2NUM(arg));
653
677
  } else if (GMPQ_P(arg)) {
654
678
  return r_gmpq_mul(arg, self);
655
679
  } else if (GMPF_P(arg)) {
680
+ #ifndef MPFR
656
681
  return r_gmpf_mul(arg, self);
682
+ #else
683
+ return rb_funcall(arg, rb_intern("*"), 1, self);
684
+ #endif
657
685
  } else if (BIGNUM_P(arg)) {
658
686
  mpz_make_struct_init(res, res_val);
659
687
  mpz_set_bignum(res_val, arg);
@@ -664,6 +692,57 @@ VALUE r_gmpz_mul(VALUE self, VALUE arg)
664
692
  return res;
665
693
  }
666
694
 
695
+ /*
696
+ * call-seq:
697
+ * a.addmul!(b, c)
698
+ *
699
+ * From the GMP Manual:
700
+ *
701
+ * Sets +a+ to +a+ plus +b+ times +c+.
702
+ */
703
+ VALUE r_gmpz_addmul_self(VALUE self, VALUE b, VALUE c)
704
+ {
705
+ MP_INT *self_val, *b_val, *c_val;
706
+ int free_b_val = 0;
707
+
708
+ if (GMPZ_P(b)) {
709
+ mpz_get_struct(b, b_val);
710
+ } else if (FIXNUM_P(b)) {
711
+ mpz_temp_alloc(b_val);
712
+ mpz_init_set_si(b_val, FIX2NUM(b));
713
+ free_b_val = 1;
714
+ } else if (BIGNUM_P(b)) {
715
+ mpz_temp_from_bignum(b_val, b);
716
+ free_b_val = 1;
717
+ } else {
718
+ typeerror_as(ZXB, "addend");
719
+ }
720
+ mpz_get_struct(self, self_val);
721
+
722
+ if (GMPZ_P(c)) {
723
+ mpz_get_struct(c, c_val);
724
+ mpz_addmul(self_val, b_val, c_val);
725
+ } else if (FIXNUM_P(c)) {
726
+ if (FIX2NUM(c) < 0)
727
+ {
728
+ if (free_b_val) { mpz_temp_free(b_val); }
729
+ rb_raise(rb_eRangeError, "multiplicand (Fixnum) must be nonnegative");
730
+ }
731
+ mpz_addmul_ui(self_val, b_val, FIX2NUM(c));
732
+ } else if (BIGNUM_P(c)) {
733
+ mpz_temp_from_bignum(c_val, c);
734
+ mpz_addmul(self_val, b_val, c_val);
735
+ mpz_temp_free(c_val);
736
+ } else {
737
+ if (free_b_val)
738
+ mpz_temp_free(b_val);
739
+ typeerror_as(ZXB, "multiplicand");
740
+ }
741
+ if (free_b_val)
742
+ mpz_temp_free(b_val);
743
+ return self;
744
+ }
745
+
667
746
  /*
668
747
  * Document-method: <<
669
748
  *
@@ -746,7 +825,11 @@ VALUE r_gmpz_div(VALUE self, VALUE arg)
746
825
  MP_RAT *arg_val_q, *res_val_q;
747
826
  MP_FLOAT *arg_val_f, *res_val_f;
748
827
  VALUE res;
828
+ #if defined(MPFR) && MPFR_VERSION_MAJOR>2
829
+ mpfr_prec_t prec;
830
+ #else
749
831
  unsigned int prec;
832
+ #endif
750
833
 
751
834
  mpz_get_struct (self,self_val);
752
835
 
@@ -759,11 +842,11 @@ VALUE r_gmpz_div(VALUE self, VALUE arg)
759
842
  mpq_set_den (res_val_q, arg_val_z);
760
843
  mpq_canonicalize (res_val_q);
761
844
  } else if (FIXNUM_P (arg)) {
762
- if (FIX2INT (arg) == 0)
845
+ if (FIX2NUM (arg) == 0)
763
846
  rb_raise (rb_eZeroDivError, "divided by 0");
764
847
  mpq_make_struct_init (res, res_val_q);
765
848
  mpq_set_num (res_val_q, self_val);
766
- mpz_set_ui (mpq_denref (res_val_q), FIX2INT (arg));
849
+ mpz_set_ui (mpq_denref (res_val_q), FIX2NUM (arg));
767
850
  mpq_canonicalize (res_val_q);
768
851
  } else if (GMPQ_P (arg)) {
769
852
  mpq_get_struct (arg, arg_val_q);
@@ -922,7 +1005,7 @@ VALUE r_gmpz_mod(VALUE self, VALUE arg)
922
1005
  mpz_mod(res_val, self_val, arg_val);
923
1006
  } else if (FIXNUM_P(arg)) {
924
1007
  mpz_make_struct_init(res, res_val);
925
- mpz_mod_ui(res_val, self_val, FIX2INT(arg));
1008
+ mpz_mod_ui(res_val, self_val, FIX2NUM(arg));
926
1009
  } else if (BIGNUM_P(arg)) {
927
1010
  mpz_make_struct_init(res, res_val);
928
1011
  mpz_set_bignum(res_val, arg);
@@ -974,11 +1057,11 @@ VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
974
1057
  rb_raise(rb_eRangeError, "modulus must be positive");
975
1058
  }
976
1059
  } else if (FIXNUM_P(mod)) {
977
- if (FIX2INT(mod) <= 0) {
1060
+ if (FIX2NUM(mod) <= 0) {
978
1061
  rb_raise(rb_eRangeError, "modulus must be positive");
979
1062
  }
980
1063
  mpz_temp_alloc(mod_val);
981
- mpz_init_set_ui(mod_val, FIX2INT(mod));
1064
+ mpz_init_set_ui(mod_val, FIX2NUM(mod));
982
1065
  free_mod_val = 1;
983
1066
  } else if (BIGNUM_P(mod)) {
984
1067
  mpz_temp_from_bignum(mod_val, mod);
@@ -1000,13 +1083,13 @@ VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
1000
1083
  }
1001
1084
  mpz_powm(res_val, self_val, exp_val, mod_val);
1002
1085
  } else if (FIXNUM_P(exp)) {
1003
- if (FIX2INT(exp) < 0)
1086
+ if (FIX2NUM(exp) < 0)
1004
1087
  {
1005
1088
  if (free_mod_val)
1006
1089
  mpz_temp_free(mod_val);
1007
1090
  rb_raise(rb_eRangeError, "exponent must be nonnegative");
1008
1091
  }
1009
- mpz_powm_ui(res_val, self_val, FIX2INT(exp), mod_val);
1092
+ mpz_powm_ui(res_val, self_val, FIX2NUM(exp), mod_val);
1010
1093
  } else if (BIGNUM_P(exp)) {
1011
1094
  mpz_temp_from_bignum(exp_val, exp);
1012
1095
  mpz_powm(res_val, self_val, exp_val, mod_val);
@@ -1141,17 +1224,17 @@ VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self)
1141
1224
  MP_INT *self_val;
1142
1225
  int reps_val;
1143
1226
  VALUE reps;
1144
- mpz_get_struct(self, self_val);
1145
- rb_scan_args(argc, argv, "01", &reps);
1227
+ mpz_get_struct (self, self_val);
1228
+ rb_scan_args (argc, argv, "01", &reps);
1146
1229
  if(NIL_P(reps)){
1147
- reps = INT2FIX(5);
1230
+ reps = INT2FIX (5);
1148
1231
  }
1149
- if (FIXNUM_P(reps)) {
1232
+ if (FIXNUM_P (reps)) {
1150
1233
  reps_val = FIX2INT (reps);
1151
1234
  } else {
1152
- typeerror_as(X, "reps");
1235
+ typeerror_as (X, "reps");
1153
1236
  }
1154
- return INT2FIX(mpz_probab_prime_p(self_val, reps_val));
1237
+ return INT2FIX (mpz_probab_prime_p(self_val, reps_val));
1155
1238
  }
1156
1239
 
1157
1240
  /*
@@ -1199,7 +1282,7 @@ VALUE r_gmpz_gcd(VALUE self, VALUE arg)
1199
1282
  mpz_gcd (res_val, self_val, arg_val);
1200
1283
  } else if (FIXNUM_P (arg)) {
1201
1284
  mpz_make_struct_init (res, res_val);
1202
- mpz_gcd_ui (res_val, self_val, FIX2INT(arg));
1285
+ mpz_gcd_ui (res_val, self_val, FIX2NUM(arg));
1203
1286
  } else if (BIGNUM_P (arg)) {
1204
1287
  mpz_make_struct_init (res, res_val);
1205
1288
  mpz_set_bignum (res_val, arg);
@@ -1223,7 +1306,7 @@ VALUE r_gmpz_invert(VALUE self, VALUE arg)
1223
1306
  mpz_invert (res_val, self_val, arg_val);
1224
1307
  } else if (FIXNUM_P (arg)) {
1225
1308
  mpz_temp_alloc(arg_val);
1226
- mpz_init_set_ui(arg_val, FIX2INT(arg));
1309
+ mpz_init_set_ui(arg_val, FIX2NUM(arg));
1227
1310
  mpz_make_struct_init (res, res_val);
1228
1311
  mpz_invert (res_val, self_val, arg_val);
1229
1312
  } else if (BIGNUM_P (arg)) {
@@ -1284,7 +1367,7 @@ VALUE r_gmpzsg_jacobi(VALUE klass, VALUE a, VALUE b)
1284
1367
  mpz_get_struct(a, a_val);
1285
1368
  } else if (FIXNUM_P(a)) {
1286
1369
  mpz_temp_alloc(a_val);
1287
- mpz_init_set_ui(a_val, FIX2INT(a));
1370
+ mpz_init_set_ui(a_val, FIX2NUM(a));
1288
1371
  free_a_val = 1;
1289
1372
  } else if (BIGNUM_P(a)) {
1290
1373
  mpz_temp_from_bignum(a_val, a);
@@ -1300,12 +1383,12 @@ VALUE r_gmpzsg_jacobi(VALUE klass, VALUE a, VALUE b)
1300
1383
  if (mpz_even_p(b_val))
1301
1384
  rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is even.");
1302
1385
  } else if (FIXNUM_P(b)) {
1303
- if (FIX2INT(b) <= 0)
1386
+ if (FIX2NUM(b) <= 0)
1304
1387
  rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is non-positive.");
1305
- if (FIX2INT(b) % 2 == 0)
1388
+ if (FIX2NUM(b) % 2 == 0)
1306
1389
  rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is even.");
1307
1390
  mpz_temp_alloc(b_val);
1308
- mpz_init_set_ui(b_val, FIX2INT(b));
1391
+ mpz_init_set_ui(b_val, FIX2NUM(b));
1309
1392
  free_b_val = 1;
1310
1393
  } else if (BIGNUM_P(b)) {
1311
1394
  mpz_temp_from_bignum(b_val, b);
@@ -1370,7 +1453,11 @@ VALUE r_gmpz_remove(VALUE self, VALUE arg)
1370
1453
  {
1371
1454
  MP_INT *self_val, *arg_val, *res_val;
1372
1455
  VALUE res;
1456
+ #if __GNU_MP_VERSION>2
1457
+ unsigned long removed_val;
1458
+ #else
1373
1459
  int removed_val;
1460
+ #endif
1374
1461
  int free_arg_val = 0;
1375
1462
 
1376
1463
  mpz_get_struct(self, self_val);
@@ -1380,10 +1467,10 @@ VALUE r_gmpz_remove(VALUE self, VALUE arg)
1380
1467
  if (mpz_sgn(arg_val) != 1)
1381
1468
  rb_raise(rb_eRangeError, "argument must be positive");
1382
1469
  } else if (FIXNUM_P(arg)) {
1383
- if (FIX2INT(arg) <= 0)
1470
+ if (FIX2NUM(arg) <= 0)
1384
1471
  rb_raise(rb_eRangeError, "argument must be positive");
1385
1472
  mpz_temp_alloc(arg_val);
1386
- mpz_init_set_ui(arg_val, FIX2INT(arg));
1473
+ mpz_init_set_ui(arg_val, FIX2NUM(arg));
1387
1474
  } else if (BIGNUM_P(arg)) {
1388
1475
  mpz_temp_from_bignum(arg_val, arg);
1389
1476
  if (mpz_sgn(arg_val) != 1) {
@@ -1459,7 +1546,7 @@ VALUE r_gmpz_eq(VALUE self, VALUE arg)
1459
1546
  mpz_get_struct(arg, arg_val_z);
1460
1547
  return (mpz_cmp (self_val, arg_val_z)==0) ? Qtrue : Qfalse;
1461
1548
  } else if (FIXNUM_P(arg)) {
1462
- return (mpz_cmp_si (self_val, FIX2INT(arg))==0) ? Qtrue : Qfalse;
1549
+ return (mpz_cmp_si (self_val, FIX2NUM(arg))==0) ? Qtrue : Qfalse;
1463
1550
  } else if (GMPQ_P(arg)) {
1464
1551
  mpq_get_struct(arg, arg_val_q);
1465
1552
  if (mpz_cmp_ui(mpq_denref(arg_val_q), 1)==0)
@@ -1489,7 +1576,7 @@ int mpz_cmp_value(MP_INT *OP, VALUE arg)
1489
1576
  mpz_get_struct(arg,arg_val_z);
1490
1577
  return mpz_cmp(OP,arg_val_z);
1491
1578
  } else if (FIXNUM_P(arg)) {
1492
- return mpz_cmp_si(OP, FIX2INT(arg));
1579
+ return mpz_cmp_si(OP, FIX2NUM(arg));
1493
1580
  } else if (GMPQ_P(arg)) {
1494
1581
  mpq_get_struct(arg,arg_val_q);
1495
1582
  mpz_temp_alloc(arg_val_z);
@@ -1573,10 +1660,10 @@ VALUE r_gmpz_cmpabs(VALUE self, VALUE arg)
1573
1660
  mpz_get_struct(arg,arg_val_z);
1574
1661
  return INT2FIX(mpz_cmpabs(self_val, arg_val_z));
1575
1662
  } else if (FIXNUM_P(arg)) {
1576
- if (FIX2INT(arg) >= 0)
1577
- return INT2FIX(mpz_cmpabs_ui(self_val, FIX2INT(arg)));
1663
+ if (FIX2NUM(arg) >= 0)
1664
+ return INT2FIX(mpz_cmpabs_ui(self_val, FIX2NUM(arg)));
1578
1665
  else
1579
- return INT2FIX(mpz_cmpabs_ui(self_val, -FIX2INT(arg)));
1666
+ return INT2FIX(mpz_cmpabs_ui(self_val, -FIX2NUM(arg)));
1580
1667
  } else if (GMPQ_P(arg)) {
1581
1668
  mpq_get_struct(arg,arg_val_q);
1582
1669
  mpz_temp_alloc(arg_val_z);
@@ -1738,13 +1825,13 @@ VALUE r_gmpz_scan0(VALUE self, VALUE bitnr)
1738
1825
  {
1739
1826
  MP_INT *self_val;
1740
1827
  int bitnr_val;
1741
- mpz_get_struct(self, self_val);
1742
- if (FIXNUM_P(bitnr)) {
1828
+ mpz_get_struct (self, self_val);
1829
+ if (FIXNUM_P (bitnr)) {
1743
1830
  bitnr_val = FIX2INT (bitnr);
1744
1831
  } else {
1745
- typeerror_as(X, "index");
1832
+ typeerror_as (X, "index");
1746
1833
  }
1747
- return INT2FIX(mpz_scan0(self_val, bitnr_val));
1834
+ return INT2FIX (mpz_scan0 (self_val, bitnr_val));
1748
1835
  }
1749
1836
 
1750
1837
  /*
@@ -1767,15 +1854,15 @@ VALUE r_gmpz_scan1(VALUE self, VALUE bitnr)
1767
1854
  MP_INT *self_val;
1768
1855
  int bitnr_val;
1769
1856
 
1770
- mpz_get_struct(self, self_val);
1857
+ mpz_get_struct (self, self_val);
1771
1858
 
1772
- if (FIXNUM_P(bitnr)) {
1859
+ if (FIXNUM_P (bitnr)) {
1773
1860
  bitnr_val = FIX2INT (bitnr);
1774
1861
  } else {
1775
- typeerror_as(X, "index");
1862
+ typeerror_as (X, "index");
1776
1863
  }
1777
1864
 
1778
- return INT2FIX(mpz_scan1(self_val, bitnr_val));
1865
+ return INT2FIX (mpz_scan1 (self_val, bitnr_val));
1779
1866
  }
1780
1867
 
1781
1868
  /*
@@ -1787,12 +1874,15 @@ VALUE r_gmpz_scan1(VALUE self, VALUE bitnr)
1787
1874
  VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to)
1788
1875
  {
1789
1876
  MP_INT *self_val;
1790
- int bitnr_val;
1877
+ unsigned long bitnr_val;
1791
1878
 
1792
1879
  mpz_get_struct (self, self_val);
1793
1880
 
1794
1881
  if (FIXNUM_P (bitnr)) {
1795
- bitnr_val = FIX2INT (bitnr);
1882
+ if (FIX2NUM (bitnr) < 0) {
1883
+ rb_raise(rb_eRangeError, "index must be nonnegative");
1884
+ }
1885
+ bitnr_val = FIX2NUM (bitnr);
1796
1886
  } else {
1797
1887
  typeerror_as (X, "index");
1798
1888
  }
@@ -1813,10 +1903,10 @@ VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to)
1813
1903
  VALUE r_gmpz_getbit(VALUE self, VALUE bitnr)
1814
1904
  {
1815
1905
  MP_INT *self_val;
1816
- int bitnr_val;
1906
+ unsigned long bitnr_val;
1817
1907
  mpz_get_struct(self, self_val);
1818
1908
  if (FIXNUM_P(bitnr)) {
1819
- bitnr_val = FIX2INT (bitnr);
1909
+ bitnr_val = FIX2NUM (bitnr);
1820
1910
  } else {
1821
1911
  typeerror_as(X, "index");
1822
1912
  }
@@ -1872,6 +1962,24 @@ VALUE r_gmpz_size_in_bin(VALUE self)
1872
1962
  * Integer Special Functions *
1873
1963
  **********************************************************************/
1874
1964
 
1965
+ /*
1966
+ * Document-method: size
1967
+ *
1968
+ * call-seq:
1969
+ * integer.size
1970
+ *
1971
+ * From the GMP Manual:
1972
+ *
1973
+ * Return the size of <tt>integer</tt> measured in number of limbs. If
1974
+ * <tt>integer</tt> is zero, the returned value will be zero.
1975
+ */
1976
+ VALUE r_gmpz_size(VALUE self)
1977
+ {
1978
+ MP_INT *self_val;
1979
+ mpz_get_struct(self, self_val);
1980
+ return INT2FIX(mpz_size(self_val));
1981
+ }
1982
+
1875
1983
 
1876
1984
  /**********************************************************************
1877
1985
  * _unsorted_ *
@@ -1889,12 +1997,12 @@ VALUE r_gmpzsg_pow(VALUE klass, VALUE base, VALUE exp)
1889
1997
 
1890
1998
  if (FIXNUM_P(base) && FIXNUM_P(exp))
1891
1999
  {
1892
- if (FIX2INT(base) < 0)
2000
+ if (FIX2NUM(base) < 0)
1893
2001
  rb_raise (rb_eRangeError, "base must not be negative");
1894
- if (FIX2INT(exp) < 0)
2002
+ if (FIX2NUM(exp) < 0)
1895
2003
  rb_raise (rb_eRangeError, "exponent must not be negative");
1896
2004
  mpz_make_struct_init (res, res_val);
1897
- mpz_ui_pow_ui (res_val, base, exp);
2005
+ mpz_ui_pow_ui (res_val, FIX2NUM(base), FIX2NUM(exp));
1898
2006
  return res;
1899
2007
  }
1900
2008
  return r_gmpz_pow (r_gmpzsg_new(1, &base, klass), exp);
@@ -1918,17 +2026,18 @@ void init_gmpz()
1918
2026
  rb_define_method(cGMP_Z, "to_s", r_gmpz_to_s, -1);
1919
2027
 
1920
2028
  // Integer Arithmetic
1921
- rb_define_method(cGMP_Z, "+", r_gmpz_add, 1);
1922
- rb_define_method(cGMP_Z, "add!", r_gmpz_add_self, 1);
1923
- rb_define_method(cGMP_Z, "-", r_gmpz_sub, 1);
1924
- rb_define_method(cGMP_Z, "sub!", r_gmpz_sub_self, 1);
1925
- rb_define_method(cGMP_Z, "*", r_gmpz_mul, 1);
1926
- rb_define_method(cGMP_Z, "<<", r_gmpz_shl, 1);
1927
- rb_define_method(cGMP_Z, "neg", r_gmpz_neg, 0);
1928
- rb_define_method(cGMP_Z, "neg!", r_gmpz_neg_self, 0);
1929
- rb_define_method(cGMP_Z, "-@", r_gmpz_neg, 0);
1930
- rb_define_method(cGMP_Z, "abs", r_gmpz_abs, 0);
1931
- rb_define_method(cGMP_Z, "abs!", r_gmpz_abs_self, 0);
2029
+ rb_define_method(cGMP_Z, "+", r_gmpz_add, 1);
2030
+ rb_define_method(cGMP_Z, "add!", r_gmpz_add_self, 1);
2031
+ rb_define_method(cGMP_Z, "-", r_gmpz_sub, 1);
2032
+ rb_define_method(cGMP_Z, "sub!", r_gmpz_sub_self, 1);
2033
+ rb_define_method(cGMP_Z, "*", r_gmpz_mul, 1);
2034
+ rb_define_method(cGMP_Z, "addmul!", r_gmpz_addmul_self, 2);
2035
+ rb_define_method(cGMP_Z, "<<", r_gmpz_shl, 1);
2036
+ rb_define_method(cGMP_Z, "neg", r_gmpz_neg, 0);
2037
+ rb_define_method(cGMP_Z, "neg!", r_gmpz_neg_self, 0);
2038
+ rb_define_method(cGMP_Z, "-@", r_gmpz_neg, 0);
2039
+ rb_define_method(cGMP_Z, "abs", r_gmpz_abs, 0);
2040
+ rb_define_method(cGMP_Z, "abs!", r_gmpz_abs_self, 0);
1932
2041
 
1933
2042
  // Integer Division
1934
2043
  rb_define_method(cGMP_Z, "/", r_gmpz_div, 1);
@@ -1982,24 +2091,27 @@ void init_gmpz()
1982
2091
  rb_define_method(cGMP_Z, "hash", r_gmpz_hash, 0);
1983
2092
 
1984
2093
  // Integer Logic and Bit Fiddling
1985
- rb_define_method(cGMP_Z, "&", r_gmpz_and, 1);
1986
- rb_define_method(cGMP_Z, "|", r_gmpz_or, 1);
1987
- rb_define_method(cGMP_Z, "^", r_gmpz_xor, 1);
1988
- rb_define_method(cGMP_Z, "com", r_gmpz_com, 0);
1989
- rb_define_method(cGMP_Z, "com!", r_gmpz_com_self, 0);
1990
- rb_define_method(cGMP_Z, "popcount", r_gmpz_popcount, 0);
1991
- rb_define_method(cGMP_Z, "scan0", r_gmpz_scan0, 1);
1992
- rb_define_method(cGMP_Z, "scan1", r_gmpz_scan1, 1);
1993
- rb_define_method(cGMP_Z, "[]=", r_gmpz_setbit, 2);
1994
- rb_define_method(cGMP_Z, "[]", r_gmpz_getbit, 1);
2094
+ rb_define_method(cGMP_Z, "&", r_gmpz_and, 1);
2095
+ rb_define_method(cGMP_Z, "|", r_gmpz_or, 1);
2096
+ rb_define_method(cGMP_Z, "^", r_gmpz_xor, 1);
2097
+ rb_define_method(cGMP_Z, "com", r_gmpz_com, 0);
2098
+ rb_define_method(cGMP_Z, "com!", r_gmpz_com_self, 0);
2099
+ rb_define_method(cGMP_Z, "popcount", r_gmpz_popcount, 0);
2100
+ rb_define_method(cGMP_Z, "scan0", r_gmpz_scan0, 1);
2101
+ rb_define_method(cGMP_Z, "scan1", r_gmpz_scan1, 1);
2102
+ rb_define_method(cGMP_Z, "[]=", r_gmpz_setbit, 2);
2103
+ rb_define_method(cGMP_Z, "[]", r_gmpz_getbit, 1);
1995
2104
 
1996
- //Miscellaneous Integer Functions
2105
+ // Miscellaneous Integer Functions
1997
2106
  rb_define_method(cGMP_Z, "even?", r_gmpz_is_even, 0);
1998
2107
  rb_define_method(cGMP_Z, "odd?", r_gmpz_is_odd, 0);
1999
2108
  rb_define_method(cGMP_Z, "sizeinbase", r_gmpz_sizeinbase, 1);
2000
2109
  rb_define_alias( cGMP_Z, "size_in_base", "sizeinbase");
2001
2110
  rb_define_method(cGMP_Z, "size_in_bin", r_gmpz_size_in_bin, 0);
2002
2111
 
2112
+ // Integer Special Functions
2113
+ rb_define_method(cGMP_Z, "size", r_gmpz_size, 0);
2114
+
2003
2115
  // _unsorted_
2004
2116
  rb_define_method(cGMP_Z, ">>", r_gmpz_fshr, 1);
2005
2117
  rb_define_method(cGMP_Z, "tshr", r_gmpz_tshr, 1);