gmp 0.4.7-x86-mingw32 → 0.5.3-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/CHANGELOG +31 -0
  2. data/README.rdoc +16 -8
  3. data/benchmark/gexpr +0 -0
  4. data/benchmark/multiply +1 -1
  5. data/benchmark/multiply.gc +57 -0
  6. data/benchmark/pi +126 -0
  7. data/benchmark/srb.sh +21 -0
  8. data/ext/extconf.rb +3 -0
  9. data/ext/gmp.c +16 -7
  10. data/ext/gmp.so +0 -0
  11. data/ext/gmpbench_timing.c +1 -1
  12. data/ext/gmpf.c +445 -104
  13. data/ext/gmpq.c +25 -17
  14. data/ext/gmpz.c +232 -120
  15. data/ext/libmpfr-4.dll +0 -0
  16. data/ext/mprnd.c +23 -5
  17. data/ext/ruby_gmp.h +75 -9
  18. data/lib/gmp.rb +9 -0
  19. data/manual.pdf +0 -0
  20. data/manual.tex +494 -60
  21. data/test/README +1 -0
  22. data/test/mpfr_tcbrt.rb +95 -0
  23. data/test/mpfr_tisnan.rb +70 -0
  24. data/test/mpfr_trec_sqrt.rb +62 -0
  25. data/test/mpfr_tsqrt.rb +142 -6
  26. data/test/tc_cmp.rb +4 -4
  27. data/test/tc_constants.rb +10 -0
  28. data/test/tc_division.rb +13 -2
  29. data/test/tc_f_arithmetics_coersion.rb +2 -2
  30. data/test/tc_f_precision.rb +4 -3
  31. data/test/tc_fib_fac_nextprime.rb +2 -2
  32. data/test/tc_floor_ceil_truncate.rb +2 -2
  33. data/test/tc_hashes.rb +0 -2
  34. data/test/tc_logical_roots.rb +1 -3
  35. data/test/tc_mpfr_constants.rb +11 -0
  36. data/test/tc_mpfr_functions.rb +22 -9
  37. data/test/tc_mpfr_random.rb +1 -3
  38. data/test/tc_mpfr_rounding.rb +10 -7
  39. data/test/tc_q.rb +1 -3
  40. data/test/tc_q_basic.rb +3 -5
  41. data/test/tc_random.rb +1 -3
  42. data/test/tc_sgn_neg_abs.rb +1 -3
  43. data/test/tc_swap.rb +1 -3
  44. data/test/tc_z.rb +3 -3
  45. data/test/tc_z_addmul.rb +92 -0
  46. data/test/tc_z_basic.rb +6 -8
  47. data/test/tc_z_exponentiation.rb +1 -3
  48. data/test/tc_z_gcd_lcm_invert.rb +1 -3
  49. data/test/tc_z_jac_leg_rem.rb +1 -3
  50. data/test/tc_z_logic.rb +2 -2
  51. data/test/tc_z_shifts_last_bits.rb +2 -2
  52. data/test/tc_z_to_d_to_i.rb +2 -2
  53. data/test/test_helper.rb +1 -1
  54. data/test/test_unit/assertions.rb +31 -0
  55. data/test/unit_tests.rb +33 -27
  56. metadata +35 -8
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);