gmp 0.5.23-x86-mingw32 → 0.5.41-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +13 -0
- data/FEATURES.html +145 -2
- data/README.rdoc +70 -68
- data/benchmark/multiply.fnl +47 -0
- data/ext/extconf.rb +4 -0
- data/ext/gmp.so +0 -0
- data/ext/gmpf.c +1 -0
- data/ext/gmpz.c +302 -4
- data/ext/ruby_gmp.h +10 -4
- data/manual.pdf +0 -0
- data/manual.tex +84 -61
- data/test/tc_f_precision.rb +1 -1
- data/test/tc_hashes.rb +2 -0
- data/test/tc_logical_roots.rb +2 -0
- data/test/tc_mpfr_constants.rb +2 -0
- data/test/tc_mpfr_functions.rb +2 -0
- data/test/tc_mpfr_random.rb +2 -0
- data/test/tc_mpfr_rounding.rb +2 -0
- data/test/tc_q.rb +2 -0
- data/test/tc_q_basic.rb +2 -0
- data/test/tc_random.rb +2 -0
- data/test/tc_sgn_neg_abs.rb +2 -0
- data/test/tc_swap.rb +2 -0
- data/test/tc_z.rb +2 -2
- data/test/tc_z_addmul.rb +2 -0
- data/test/tc_z_basic.rb +2 -0
- data/test/tc_z_exponentiation.rb +3 -1
- data/test/tc_z_functional_mappings.rb +100 -0
- data/test/tc_z_gcd_lcm_invert.rb +2 -0
- data/test/tc_z_jac_leg_rem.rb +2 -0
- data/test/tc_zerodivisionexceptions.rb +3 -1
- data/test/unit_tests.rb +5 -4
- metadata +6 -4
data/ext/gmpz.c
CHANGED
@@ -180,6 +180,280 @@ static VALUE r_gmpz_##fname(VALUE self) \
|
|
180
180
|
return mpz_fname (self_val) ? Qtrue : Qfalse; \
|
181
181
|
}
|
182
182
|
|
183
|
+
|
184
|
+
/**********************************************************************
|
185
|
+
* Functional Mappings *
|
186
|
+
**********************************************************************/
|
187
|
+
|
188
|
+
/*
|
189
|
+
* 01 mpz_t__mpz_t_or_ui__to__mpz_t__returns__void
|
190
|
+
* FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID defines a GMP::Z singleton function that takes a
|
191
|
+
* GMP::Z as rop, a GMP::Z as op1, and a GMP::Z, Bignum, or Fixnum as op2. It calls
|
192
|
+
* mpz_fname, whose arguments are rop (the return argument), op1, and op2. If op2 is a
|
193
|
+
* Fixnum, and >= 0, the ui variant of mpz_fname will be used.
|
194
|
+
*
|
195
|
+
* TODO: Accept Fixnum, Bignum as op1 and just convert to GMP::Z.
|
196
|
+
*/
|
197
|
+
#define FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(fname,mpz_fname) \
|
198
|
+
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1, VALUE op2) \
|
199
|
+
{ \
|
200
|
+
MP_INT *rop_val, *op1_val, *op2_val; \
|
201
|
+
(void)klass; \
|
202
|
+
\
|
203
|
+
if (! GMPZ_P (rop)) { \
|
204
|
+
typeerror_as(Z, "rop"); \
|
205
|
+
} \
|
206
|
+
mpz_get_struct (rop, rop_val); \
|
207
|
+
\
|
208
|
+
if (! GMPZ_P (op1)) { \
|
209
|
+
typeerror_as (Z, "op1"); \
|
210
|
+
} \
|
211
|
+
mpz_get_struct (op1, op1_val); \
|
212
|
+
\
|
213
|
+
if (FIXNUM_P (op2)) { \
|
214
|
+
if (FIX2NUM (op2) >= 0) { \
|
215
|
+
mpz_fname##_ui (rop_val, op1_val, FIX2NUM (op2)); \
|
216
|
+
} else { \
|
217
|
+
mpz_set_si (rop_val, FIX2NUM (op2)); \
|
218
|
+
mpz_fname (rop_val, op1_val, rop_val); \
|
219
|
+
} \
|
220
|
+
} else if (BIGNUM_P (op2)) { \
|
221
|
+
mpz_set_bignum (rop_val, op2); \
|
222
|
+
mpz_fname (rop_val, op1_val, rop_val); \
|
223
|
+
} else if (GMPZ_P (op2)) { \
|
224
|
+
mpz_get_struct (op2, op2_val); \
|
225
|
+
mpz_fname (rop_val, op1_val, op2_val); \
|
226
|
+
} else { \
|
227
|
+
typeerror_as (ZXB, "op2"); \
|
228
|
+
} \
|
229
|
+
\
|
230
|
+
return Qnil; \
|
231
|
+
}
|
232
|
+
|
233
|
+
/*
|
234
|
+
* Document-method: GMP::Z.add
|
235
|
+
*
|
236
|
+
* call-seq:
|
237
|
+
* GMP::Z.add(rop, op1, op2)
|
238
|
+
*
|
239
|
+
* ...
|
240
|
+
*/
|
241
|
+
FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(add,mpz_add)
|
242
|
+
FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(addmul,mpz_addmul)
|
243
|
+
FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(submul,mpz_submul)
|
244
|
+
FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(divexact,mpz_divexact)
|
245
|
+
FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(lcm,mpz_lcm)
|
246
|
+
|
247
|
+
/*
|
248
|
+
* 02 mpz_t_or_ui__mpz_t_or_ui__to__mpz_t__returns__void
|
249
|
+
* FUNC_MAP__ZUI_ZUI__TO__Z__RETURNS__VOID defines a GMP::Z singleton function that takes
|
250
|
+
* a GMP::Z as rop, a GMP::Z, Bignum, or Fixnum as op1, and a GMP::Z, Bignum, or Fixnum
|
251
|
+
* as op2. It calls mpz_fname, whose arguments are rop (the return argument), op1, and
|
252
|
+
* op2. If op1 is a Fixnum and >=0, xor if op2 is a Fixnum and >= 0, one ui variant or
|
253
|
+
* the other of mpz_fname will be used:
|
254
|
+
*
|
255
|
+
* op2 --> | FIXNUM >=0 | FIXNUM < 0 | BIGNUM | GMP::Z |
|
256
|
+
* v op1 v +--------------+--------------+--------------+--------------+
|
257
|
+
* FIXNUM >= 0 | mpz_ui_fname | mpz_ui_fname | mpz_ui_fname | mpz_ui_fname |
|
258
|
+
* FIXNUM < 0 | mpz_fname_ui | mpz_fname | mpz_fname | mpz_fname |
|
259
|
+
* BIGNUM | mpz_fname_ui | mpz_fname | mpz_fname | mpz_fname |
|
260
|
+
* GMP::Z | mpz_fname_ui | mpz_fname | mpz_fname | mpz_fname |
|
261
|
+
*
|
262
|
+
* TODO: Maybe take si's, negate them, and perform mpz_additive_inverse_fname *choke*
|
263
|
+
*/
|
264
|
+
#define FUNC_MAP__ZUI_ZUI__TO__Z__RETURNS__VOID(fname,mpz_fname) \
|
265
|
+
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1, VALUE op2) \
|
266
|
+
{ \
|
267
|
+
MP_INT *rop_val, *op1_val, *op2_val; \
|
268
|
+
int free_op1_val = 0; \
|
269
|
+
(void)klass; \
|
270
|
+
\
|
271
|
+
if (! GMPZ_P (rop)) { \
|
272
|
+
typeerror_as(Z, "rop"); \
|
273
|
+
} \
|
274
|
+
mpz_get_struct (rop, rop_val); \
|
275
|
+
\
|
276
|
+
if (FIXNUM_P (op1) && FIX2NUM (op1) >= 0) { \
|
277
|
+
if (FIXNUM_P (op2)) { \
|
278
|
+
mpz_set_si (rop_val, FIX2NUM (op2)); \
|
279
|
+
mpz_ui_##fname (rop_val, FIX2NUM (op1), rop_val); \
|
280
|
+
} else if (BIGNUM_P (op2)) { \
|
281
|
+
mpz_set_bignum (rop_val, op2); \
|
282
|
+
mpz_ui_##fname (rop_val, FIX2NUM (op1), rop_val); \
|
283
|
+
} else if (GMPZ_P (op2)) { \
|
284
|
+
mpz_get_struct (op2, op2_val); \
|
285
|
+
mpz_ui_##fname (rop_val, FIX2NUM (op1), op2_val); \
|
286
|
+
} else { \
|
287
|
+
typeerror_as (ZXB, "op2"); \
|
288
|
+
} \
|
289
|
+
} else { \
|
290
|
+
if (FIXNUM_P (op1)) { \
|
291
|
+
mpz_temp_alloc (op1_val); \
|
292
|
+
mpz_init_set_si (op1_val, FIX2NUM (op1)); \
|
293
|
+
free_op1_val = 1; \
|
294
|
+
} else if (BIGNUM_P (op1)) { \
|
295
|
+
mpz_temp_from_bignum (op1_val, op1); \
|
296
|
+
free_op1_val = 1; \
|
297
|
+
} else if (GMPZ_P (op1)) { \
|
298
|
+
mpz_get_struct (op1, op1_val); \
|
299
|
+
} else { \
|
300
|
+
typeerror_as (ZXB, "op1"); \
|
301
|
+
} \
|
302
|
+
\
|
303
|
+
if (FIXNUM_P (op2)) { \
|
304
|
+
if (FIX2NUM (op2) >= 0) { \
|
305
|
+
mpz_fname##_ui (rop_val, op1_val, FIX2NUM (op2)); \
|
306
|
+
} else { \
|
307
|
+
mpz_set_si (rop_val, FIX2NUM (op2)); \
|
308
|
+
mpz_fname (rop_val, op1_val, rop_val); \
|
309
|
+
} \
|
310
|
+
} else if (BIGNUM_P (op2)) { \
|
311
|
+
mpz_set_bignum (rop_val, op2); \
|
312
|
+
mpz_fname (rop_val, op1_val, rop_val); \
|
313
|
+
} else if (GMPZ_P (op2)) { \
|
314
|
+
mpz_get_struct (op2, op2_val); \
|
315
|
+
mpz_fname (rop_val, op1_val, op2_val); \
|
316
|
+
} else { \
|
317
|
+
typeerror_as (ZXB, "op2"); \
|
318
|
+
} \
|
319
|
+
\
|
320
|
+
if (free_op1_val) \
|
321
|
+
mpz_temp_free (op1_val); \
|
322
|
+
} \
|
323
|
+
\
|
324
|
+
return Qnil; \
|
325
|
+
}
|
326
|
+
|
327
|
+
FUNC_MAP__ZUI_ZUI__TO__Z__RETURNS__VOID(sub,mpz_sub)
|
328
|
+
|
329
|
+
/*
|
330
|
+
* 03 mpz_t__mpz_t_or_si_or_ui__to__mpz_t__returns__void
|
331
|
+
* FUNC_MAP__Z_ZSIUI__TO__Z__RETURNS__VOID defines a GMP::Z singleton function that takes
|
332
|
+
* a GMP::Z as rop, a GMP::Z as op1, and a GMP::Z, Bignum, or Fixnum as op2. It calls
|
333
|
+
* mpz_fname, whose arguments are rop (the return argument), op1, and op2. If op2 is a
|
334
|
+
* Fixnum, then if op2 >= 0 the ui variant of mpz_fname (else the si variant of
|
335
|
+
* mpz_fname) will be used.
|
336
|
+
*
|
337
|
+
* TODO: Accept Fixnum, Bignum as op1 and just convert to GMP::Z.
|
338
|
+
*/
|
339
|
+
#define FUNC_MAP__Z_ZSIUI__TO__Z__RETURNS__VOID(fname,mpz_fname) \
|
340
|
+
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1, VALUE op2) \
|
341
|
+
{ \
|
342
|
+
MP_INT *rop_val, *op1_val, *op2_val; \
|
343
|
+
(void)klass; \
|
344
|
+
\
|
345
|
+
if (! GMPZ_P (rop)) { \
|
346
|
+
typeerror_as(Z, "rop"); \
|
347
|
+
} \
|
348
|
+
mpz_get_struct (rop, rop_val); \
|
349
|
+
\
|
350
|
+
if (! GMPZ_P (op1)) { \
|
351
|
+
typeerror_as (Z, "op1"); \
|
352
|
+
} \
|
353
|
+
mpz_get_struct (op1, op1_val); \
|
354
|
+
\
|
355
|
+
if (FIXNUM_P (op2)) { \
|
356
|
+
if (FIX2NUM (op2) >= 0) { \
|
357
|
+
mpz_fname##_ui (rop_val, op1_val, FIX2NUM (op2)); \
|
358
|
+
} else { \
|
359
|
+
mpz_fname##_si (rop_val, op1_val, FIX2NUM (op2)); \
|
360
|
+
} \
|
361
|
+
} else if (BIGNUM_P (op2)) { \
|
362
|
+
mpz_set_bignum (rop_val, op2); \
|
363
|
+
mpz_fname (rop_val, op1_val, rop_val); \
|
364
|
+
} else if (GMPZ_P (op2)) { \
|
365
|
+
mpz_get_struct (op2, op2_val); \
|
366
|
+
mpz_fname (rop_val, op1_val, op2_val); \
|
367
|
+
} else { \
|
368
|
+
typeerror_as (ZXB, "op2"); \
|
369
|
+
} \
|
370
|
+
\
|
371
|
+
return Qnil; \
|
372
|
+
}
|
373
|
+
|
374
|
+
FUNC_MAP__Z_ZSIUI__TO__Z__RETURNS__VOID(mul,mpz_mul)
|
375
|
+
|
376
|
+
/*
|
377
|
+
* 04 mpz_t__mp_bitcnt_t__to__mpz_t__returns__void
|
378
|
+
* FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID defines a GMP::Z singleton function that takes a
|
379
|
+
* GMP::Z as rop, a GMP::Z as op1, and a Fixnum as op2. It calls mpz_fname, whose
|
380
|
+
* arguments are rop (the return argument), op1, and op2. op2 must be >= 0.
|
381
|
+
*
|
382
|
+
* TODO: Accept Fixnum, Bignum as op1 and just convert to GMP::Z.
|
383
|
+
*/
|
384
|
+
#define FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(fname,mpz_fname) \
|
385
|
+
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1, VALUE op2) \
|
386
|
+
{ \
|
387
|
+
MP_INT *rop_val, *op1_val; \
|
388
|
+
(void)klass; \
|
389
|
+
\
|
390
|
+
if (! GMPZ_P (rop)) { \
|
391
|
+
typeerror_as(Z, "rop"); \
|
392
|
+
} \
|
393
|
+
mpz_get_struct (rop, rop_val); \
|
394
|
+
\
|
395
|
+
if (! GMPZ_P (op1)) { \
|
396
|
+
typeerror_as (Z, "op1"); \
|
397
|
+
} \
|
398
|
+
mpz_get_struct (op1, op1_val); \
|
399
|
+
\
|
400
|
+
if (! FIXNUM_P (op2)) { \
|
401
|
+
typeerror_as (X, "op2"); \
|
402
|
+
} \
|
403
|
+
\
|
404
|
+
if (FIX2NUM (op2) >= 0) { \
|
405
|
+
mpz_fname (rop_val, op1_val, FIX2NUM (op2)); \
|
406
|
+
} else { \
|
407
|
+
rb_raise(rb_eRangeError, "op2 (Fixnum) must be nonnegative"); \
|
408
|
+
} \
|
409
|
+
\
|
410
|
+
return Qnil; \
|
411
|
+
}
|
412
|
+
|
413
|
+
FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(mul_2exp,mpz_mul_2exp)
|
414
|
+
FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(cdiv_q_2exp,mpz_cdiv_q_2exp)
|
415
|
+
FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(cdiv_r_2exp,mpz_cdiv_r_2exp)
|
416
|
+
FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(fdiv_q_2exp,mpz_fdiv_q_2exp)
|
417
|
+
FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(fdiv_r_2exp,mpz_fdiv_r_2exp)
|
418
|
+
FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(tdiv_q_2exp,mpz_tdiv_q_2exp)
|
419
|
+
FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(tdiv_r_2exp,mpz_tdiv_r_2exp)
|
420
|
+
|
421
|
+
/*
|
422
|
+
* 05 mpz_t__mpz_t__to__mpz_t__returns__void
|
423
|
+
* FUNC_MAP__Z__TO__Z__RETURNS__VOID defines a GMP::Z singleton function that takes a
|
424
|
+
* GMP::Z as rop, and a GMP::Z as op1. It calls mpz_fname, whose arguments are rop (the
|
425
|
+
* return argument), and op1.
|
426
|
+
*
|
427
|
+
* TODO: Accept Fixnum, Bignum as op1 and just convert to GMP::Z.
|
428
|
+
*/
|
429
|
+
#define FUNC_MAP__Z__TO__Z__RETURNS__VOID(fname,mpz_fname) \
|
430
|
+
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1) \
|
431
|
+
{ \
|
432
|
+
MP_INT *rop_val, *op1_val; \
|
433
|
+
(void)klass; \
|
434
|
+
\
|
435
|
+
if (! GMPZ_P (rop)) { \
|
436
|
+
typeerror_as(Z, "rop"); \
|
437
|
+
} \
|
438
|
+
mpz_get_struct (rop, rop_val); \
|
439
|
+
\
|
440
|
+
if (! GMPZ_P (op1)) { \
|
441
|
+
typeerror_as (Z, "op1"); \
|
442
|
+
} \
|
443
|
+
mpz_get_struct (op1, op1_val); \
|
444
|
+
\
|
445
|
+
mpz_fname (rop_val, op1_val); \
|
446
|
+
\
|
447
|
+
return Qnil; \
|
448
|
+
}
|
449
|
+
|
450
|
+
FUNC_MAP__Z__TO__Z__RETURNS__VOID(neg,mpz_neg)
|
451
|
+
FUNC_MAP__Z__TO__Z__RETURNS__VOID(abs,mpz_abs)
|
452
|
+
FUNC_MAP__Z__TO__Z__RETURNS__VOID(sqrt,mpz_sqrt)
|
453
|
+
FUNC_MAP__Z__TO__Z__RETURNS__VOID(nextprime,mpz_nextprime)
|
454
|
+
FUNC_MAP__Z__TO__Z__RETURNS__VOID(com,mpz_com)
|
455
|
+
|
456
|
+
|
183
457
|
/**********************************************************************
|
184
458
|
* Initializing, Assigning Integers *
|
185
459
|
**********************************************************************/
|
@@ -1612,10 +1886,10 @@ DEFUN_INT_SINGLETON_UI(fac, mpz_fac_ui)
|
|
1612
1886
|
* * GMP::Z.fib(1) #=> 1
|
1613
1887
|
* * GMP::Z.fib(2) #=> 1
|
1614
1888
|
* * GMP::Z.fib(3) #=> 2
|
1615
|
-
* * GMP::Z.
|
1616
|
-
* * GMP::Z.
|
1617
|
-
* * GMP::Z.
|
1618
|
-
* * GMP::Z.
|
1889
|
+
* * GMP::Z.fib(4) #=> 3
|
1890
|
+
* * GMP::Z.fib(5) #=> 5
|
1891
|
+
* * GMP::Z.fib(6) #=> 8
|
1892
|
+
* * GMP::Z.fib(7) #=> 13
|
1619
1893
|
*/
|
1620
1894
|
DEFUN_INT_SINGLETON_UI(fib, mpz_fib_ui)
|
1621
1895
|
|
@@ -2155,6 +2429,15 @@ void init_gmpz()
|
|
2155
2429
|
rb_define_method(cGMP_Z, "-@", r_gmpz_neg, 0);
|
2156
2430
|
rb_define_method(cGMP_Z, "abs", r_gmpz_abs, 0);
|
2157
2431
|
rb_define_method(cGMP_Z, "abs!", r_gmpz_abs_self, 0);
|
2432
|
+
// Functional Mappings
|
2433
|
+
rb_define_singleton_method(cGMP_Z, "add", r_gmpzsg_add, 3);
|
2434
|
+
rb_define_singleton_method(cGMP_Z, "sub", r_gmpzsg_sub, 3);
|
2435
|
+
rb_define_singleton_method(cGMP_Z, "mul", r_gmpzsg_mul, 3);
|
2436
|
+
rb_define_singleton_method(cGMP_Z, "addmul", r_gmpzsg_addmul, 3);
|
2437
|
+
rb_define_singleton_method(cGMP_Z, "submul", r_gmpzsg_submul, 3);
|
2438
|
+
rb_define_singleton_method(cGMP_Z, "mul_2exp", r_gmpzsg_mul_2exp, 3);
|
2439
|
+
rb_define_singleton_method(cGMP_Z, "neg", r_gmpzsg_neg, 2);
|
2440
|
+
rb_define_singleton_method(cGMP_Z, "abs", r_gmpzsg_abs, 2);
|
2158
2441
|
|
2159
2442
|
// Integer Division
|
2160
2443
|
rb_define_method(cGMP_Z, "/", r_gmpz_div, 1);
|
@@ -2168,6 +2451,14 @@ void init_gmpz()
|
|
2168
2451
|
rb_define_method(cGMP_Z, "cmod", r_gmpz_cmod, 1);
|
2169
2452
|
rb_define_method(cGMP_Z, "%", r_gmpz_mod, 1);
|
2170
2453
|
rb_define_method(cGMP_Z, "divisible?", r_gmpz_divisible, 1);
|
2454
|
+
// Functional Mappings
|
2455
|
+
rb_define_singleton_method(cGMP_Z, "divexact", r_gmpzsg_divexact, 3);
|
2456
|
+
rb_define_singleton_method(cGMP_Z, "cdiv_q_2exp", r_gmpzsg_cdiv_q_2exp, 3);
|
2457
|
+
rb_define_singleton_method(cGMP_Z, "cdiv_r_2exp", r_gmpzsg_cdiv_r_2exp, 3);
|
2458
|
+
rb_define_singleton_method(cGMP_Z, "fdiv_q_2exp", r_gmpzsg_fdiv_q_2exp, 3);
|
2459
|
+
rb_define_singleton_method(cGMP_Z, "fdiv_r_2exp", r_gmpzsg_fdiv_r_2exp, 3);
|
2460
|
+
rb_define_singleton_method(cGMP_Z, "tdiv_q_2exp", r_gmpzsg_tdiv_q_2exp, 3);
|
2461
|
+
rb_define_singleton_method(cGMP_Z, "tdiv_r_2exp", r_gmpzsg_tdiv_r_2exp, 3);
|
2171
2462
|
|
2172
2463
|
// Integer Exponentiation
|
2173
2464
|
rb_define_singleton_method(cGMP_Z, "pow", r_gmpzsg_pow, 2);
|
@@ -2181,6 +2472,8 @@ void init_gmpz()
|
|
2181
2472
|
rb_define_method(cGMP_Z, "sqrtrem", r_gmpz_sqrtrem, 0);
|
2182
2473
|
rb_define_method(cGMP_Z, "square?", r_gmpz_is_square, 0);
|
2183
2474
|
rb_define_method(cGMP_Z, "power?", r_gmpz_is_power, 0);
|
2475
|
+
// Functional Mappings
|
2476
|
+
rb_define_singleton_method(cGMP_Z, "sqrt", r_gmpzsg_sqrt, 2);
|
2184
2477
|
|
2185
2478
|
// Number Theoretic Functions
|
2186
2479
|
rb_define_method( cGMP_Z, "probab_prime?", r_gmpz_is_probab_prime, -1);
|
@@ -2197,6 +2490,9 @@ void init_gmpz()
|
|
2197
2490
|
rb_define_method( cGMP_Z, "remove", r_gmpz_remove, 1);
|
2198
2491
|
rb_define_singleton_method(cGMP_Z, "fac", r_gmpzsg_fac, 1);
|
2199
2492
|
rb_define_singleton_method(cGMP_Z, "fib", r_gmpzsg_fib, 1);
|
2493
|
+
// Functional Mappings
|
2494
|
+
rb_define_singleton_method(cGMP_Z, "lcm", r_gmpzsg_lcm, 3);
|
2495
|
+
rb_define_singleton_method(cGMP_Z, "nextprime", r_gmpzsg_nextprime, 2);
|
2200
2496
|
|
2201
2497
|
// Integer Comparisons
|
2202
2498
|
rb_define_method(cGMP_Z, "<=>", r_gmpz_cmp, 1);
|
@@ -2222,6 +2518,8 @@ void init_gmpz()
|
|
2222
2518
|
rb_define_method(cGMP_Z, "scan1", r_gmpz_scan1, 1);
|
2223
2519
|
rb_define_method(cGMP_Z, "[]=", r_gmpz_setbit, 2);
|
2224
2520
|
rb_define_method(cGMP_Z, "[]", r_gmpz_getbit, 1);
|
2521
|
+
// Functional Mappings
|
2522
|
+
rb_define_singleton_method(cGMP_Z, "com", r_gmpzsg_com, 2);
|
2225
2523
|
|
2226
2524
|
// Miscellaneous Integer Functions
|
2227
2525
|
rb_define_method(cGMP_Z, "even?", r_gmpz_is_even, 0);
|
data/ext/ruby_gmp.h
CHANGED
@@ -110,13 +110,19 @@ typedef __gmp_randstate_struct MP_RANDSTATE;
|
|
110
110
|
#define r_mpf_cmp(var1, var2) (mpf_cmp(var1, var2))
|
111
111
|
#endif
|
112
112
|
|
113
|
-
#
|
114
|
-
/* 64-bit */
|
113
|
+
#ifdef FIXNUM_WIDTH /* RBX check */
|
114
|
+
#if (((8*SIZEOF_INTPTR_T) - TAG_FIXNUM_SHIFT -1) == 63) /* 64-bit */
|
115
115
|
#define FIX2NUM(x) FIX2LONG(x)
|
116
|
-
#else
|
117
|
-
/* 32-bit */
|
116
|
+
#else /* 32-bit */
|
118
117
|
#define FIX2NUM(x) FIX2INT(x)
|
119
118
|
#endif
|
119
|
+
#else /* RBX check */
|
120
|
+
#if SIZEOF_INT < SIZEOF_LONG /* 64-bit */
|
121
|
+
#define FIX2NUM(x) FIX2LONG(x)
|
122
|
+
#else /* 32-bit */
|
123
|
+
#define FIX2NUM(x) FIX2INT(x)
|
124
|
+
#endif /* MRI's 32-vs-64 check */
|
125
|
+
#endif /* RBX check */
|
120
126
|
|
121
127
|
#define EXPECTED_ZQFXBD "Expected GMP::Z, GMP::Q, GMP::F, Fixnum, Bignum or Float"
|
122
128
|
#define EXPECTED_ZQFXB "Expected GMP::Z, GMP::Q, GMP::F, Fixnum or Bignum"
|
data/manual.pdf
CHANGED
Binary file
|
data/manual.tex
CHANGED
@@ -34,8 +34,8 @@
|
|
34
34
|
\huge{gmp} &\\
|
35
35
|
\midrule[3pt]
|
36
36
|
\multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\
|
37
|
-
\multicolumn{2}{r}{\large{Edition 0.5.
|
38
|
-
\multicolumn{2}{r}{\large{
|
37
|
+
\multicolumn{2}{r}{\large{Edition 0.5.41}}\\
|
38
|
+
\multicolumn{2}{r}{\large{17 November 2010}}
|
39
39
|
\end{tabular}
|
40
40
|
|
41
41
|
\vfill
|
@@ -147,9 +147,12 @@ of the following versions of Ruby:
|
|
147
147
|
\item (MRI) Ruby 1.9.1 - tested seriously.
|
148
148
|
\item (MRI) Ruby 1.9.2 - tested seriously.
|
149
149
|
\item (REE) Ruby 1.8.7 - tested lightly.
|
150
|
+
\item (RBX) Rubinius 1.1 - tested lightly.
|
150
151
|
\end{itemize}
|
151
|
-
As you can see only Matz's Ruby Interpreter (MRI) is supported. I've just
|
152
|
-
around with REE. Everything seems to work on REE 1.8.7 on Linux, x86 and
|
152
|
+
As you can see only Matz's Ruby Interpreter (MRI) is seriously supported. I've just
|
153
|
+
started to poke around with REE. Everything seems to work on REE 1.8.7 on Linux, x86 and
|
154
|
+
x86\_64. Also, Rubinius 1.1 seems to work great on Linux, but support won't be official
|
155
|
+
until Rubinius 1.1.1.\\
|
153
156
|
|
154
157
|
Next is the platform, the combination of the architecture (processor) and OS.
|
155
158
|
As far as I can tell, if you can compile GMP and Ruby (and optionally MPFR) on
|
@@ -174,35 +177,42 @@ The (MPFR) version denotes that the gmp gem was tested both with and without
|
|
174
177
|
the given version of MPFR:\\\\
|
175
178
|
|
176
179
|
\begin{tabular}{lrrr} \hline
|
177
|
-
Platform & Ruby
|
178
|
-
Linux (Ubuntu NR 10.04) on x86 (32-bit) & (MRI) Ruby 1.8.7
|
179
|
-
& (MRI) Ruby 1.8.7
|
180
|
-
& (MRI) Ruby 1.9.1
|
181
|
-
& (MRI) Ruby 1.9.1
|
182
|
-
& (MRI) Ruby 1.9.2
|
183
|
-
& (MRI) Ruby 1.9.2
|
184
|
-
|
185
|
-
& (
|
186
|
-
|
187
|
-
& (MRI) Ruby 1.
|
188
|
-
& (MRI) Ruby 1.9.
|
189
|
-
& (MRI) Ruby 1.9.
|
190
|
-
|
191
|
-
& (MRI) Ruby 1.
|
192
|
-
& (
|
193
|
-
& (
|
194
|
-
|
195
|
-
& (MRI) Ruby 1.
|
196
|
-
|
197
|
-
& (MRI) Ruby 1.
|
198
|
-
& (MRI) Ruby 1.9.
|
199
|
-
& (MRI) Ruby 1.9.
|
200
|
-
& (
|
201
|
-
& (
|
202
|
-
Windows
|
203
|
-
& (MRI) Ruby 1.
|
180
|
+
Platform & Ruby & GMP & (MPFR) \\ \midrule[1pt]
|
181
|
+
Linux (Ubuntu NR 10.04) on x86 (32-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
|
182
|
+
& (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
|
183
|
+
& (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
|
184
|
+
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
|
185
|
+
& (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
|
186
|
+
& (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\
|
187
|
+
& (RBX) Rubinius 1.1 & GMP 4.3.2 & (2.4.2) \\
|
188
|
+
& (RBX) Rubinius 1.1 & GMP 5.0.1 & (3.0.0) \\ \hline
|
189
|
+
Linux (Ubuntu 10.04) on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
|
190
|
+
& (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
|
191
|
+
& (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
|
192
|
+
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
|
193
|
+
& (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
|
194
|
+
& (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\
|
195
|
+
& (RBX) Rubinius 1.1 & GMP 4.3.2 & (2.4.2) \\
|
196
|
+
& (RBX) Rubinius 1.1 & GMP 5.0.1 & (3.0.0) \\ \hline
|
197
|
+
Mac OS X 10.6.4 on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
|
198
|
+
& (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
|
199
|
+
& (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
|
200
|
+
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
|
201
|
+
& (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
|
202
|
+
& (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\
|
203
|
+
& (RBX) Rubinius 1.1 & GMP 4.3.2 & (2.4.2) \\
|
204
|
+
& (RBX) Rubinius 1.1 & GMP 5.0.1 & (3.0.0) \\ \hline
|
205
|
+
Windows 7 on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
|
206
|
+
& (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
|
207
|
+
& (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
|
208
|
+
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
|
209
|
+
& (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
|
210
|
+
& (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
|
211
|
+
Windows XP on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
|
212
|
+
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ \hline
|
204
213
|
\end{tabular}\\\\
|
205
214
|
|
215
|
+
\newpage
|
206
216
|
In addition, I \textit{used to test} on the following environments, in versions
|
207
217
|
0.4.7 and earlier of the gmp gem:\\\\
|
208
218
|
|
@@ -1520,56 +1530,69 @@ for 'base' and 'app' are not listed; they cannot be compared with GMPbench resul
|
|
1520
1530
|
|
1521
1531
|
Mac OS X 10.6.4, x86 (32-bit)\\
|
1522
1532
|
Ruby and GMP compiled with gcc 4.2.1 (Apple Inc. build 5664)\\
|
1523
|
-
\begin{tabular}{|l|l|r|r|r|r|}
|
1533
|
+
\begin{tabular}{|l|l|r|r|r|r|r|}
|
1524
1534
|
\hline
|
1525
|
-
GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\
|
1535
|
+
GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & RBX 1.1 & C \\
|
1526
1536
|
\hline
|
1527
|
-
4.3.2 & multiply &
|
1528
|
-
& divide &
|
1529
|
-
& gcd &
|
1530
|
-
& rsa &
|
1537
|
+
4.3.2 & multiply & 7734.2 & 7505.9 & 7637.9 & 7469.3 & 16789 \\
|
1538
|
+
& divide & 7336.1 & 7180 & 7223.7 & 7121.2 & 9872.5 \\
|
1539
|
+
& gcd & 2356 & 2436.8 & 2448.8 & 2385.6 & 2938.9 \\
|
1540
|
+
& rsa & 2035.2 & 1995.3 & 2068.4 & 2051.1 & 2136.7 \\
|
1531
1541
|
\hline
|
1532
|
-
5.0.1 & multiply &
|
1533
|
-
& divide &
|
1534
|
-
& gcd &
|
1535
|
-
& rsa &
|
1542
|
+
5.0.1 & multiply & 8030.5 & 7926.7 & 8019.3 & 7944.1 & 17925 \\
|
1543
|
+
& divide & 10341 & 10070 & 10218 & 10018 & 16069 \\
|
1544
|
+
& gcd & 2501 & 2535.4 & 2578.7 & 2537.3 & 3063.7 \\
|
1545
|
+
& rsa & 2128 & 2159.1 & 2170.5 & 2162 & 2229.2 \\
|
1536
1546
|
\hline
|
1537
1547
|
\end{tabular}\\\\
|
1538
1548
|
|
1539
|
-
Ubuntu 10.04, Kernel 2.6.32-
|
1549
|
+
Ubuntu 10.04, Kernel 2.6.32-25, x86\_64 (64-bit)\\
|
1540
1550
|
Ruby and GMP compiled with gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)\\
|
1541
|
-
\begin{
|
1551
|
+
\begin{small}In these tests, the classic multiply benchmark crashes with OutOfMemory. There are
|
1552
|
+
two ways this has been remedied. The first (tests marked multiply.gc) is to manually
|
1553
|
+
kick off garbage collection every so often. This solves the memory problem in all
|
1554
|
+
interpreters except Rubinius 1.1 (investigation pending). The second, and far better
|
1555
|
+
solution is to employ the new functional mapping methods. These have not been
|
1556
|
+
documented yet, but documentation is pending, and high on my priority list. Simply
|
1557
|
+
put, these methods overcome the overhead (memory and time) of instantiating new
|
1558
|
+
objects all the time.\end{small}\\
|
1559
|
+
\begin{tabular}{|l|l|r|r|r|r|r|}
|
1542
1560
|
\hline
|
1543
|
-
GMP & bench
|
1561
|
+
GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & RBX 1.1 & C \\
|
1544
1562
|
\hline
|
1545
|
-
4.3.2 & multiply &
|
1546
|
-
&
|
1547
|
-
&
|
1548
|
-
&
|
1563
|
+
4.3.2 & multiply & x & x & x & x & 14716 \\
|
1564
|
+
& multiply.gc & 7849.2 & 6911.4 & 7703.5 & x & 14716 \\
|
1565
|
+
& multiply.fnl & 9532.6 & 11182 & 10886 & 5131.3 & 14716 \\
|
1566
|
+
& divide & 7704.6 & 7591.8 & 7527.2 & 4265.1 & 8614.3 \\
|
1567
|
+
& gcd & 2420.1 & 2453.6 & 2487.4 & 1676.4 & 2779.8 \\
|
1568
|
+
& rsa & 2040.5 & 2069.2 & 2044.2 & 1758.9 & 1984.3 \\
|
1549
1569
|
\hline
|
1550
|
-
5.0.1 & multiply &
|
1551
|
-
&
|
1552
|
-
&
|
1553
|
-
&
|
1570
|
+
5.0.1 & multiply & x & x & x & x & 17695 \\
|
1571
|
+
& multiply.gc & 8265.3 & 7289.4 & 8105.1 & x & 17695 \\
|
1572
|
+
& multiply.fnl & 10029 & 11807 & 11493 & 6036.7 & 17695 \\
|
1573
|
+
& divide & 10988 & 10935 & 10799 & 6164.9 & 15629 \\
|
1574
|
+
& gcd & 2554.2 & 2510.2 & 2538.6 & 1802.8 & 2925.1 \\
|
1575
|
+
& rsa & 2128.7 & 2189 & 2179.9 & 1941.2 & 2233.4 \\
|
1554
1576
|
\hline
|
1555
1577
|
\end{tabular}\\\\
|
1556
1578
|
|
1579
|
+
\newpage
|
1557
1580
|
Windows 7 (64-bit)\\
|
1558
1581
|
Ruby and GMP compiled with gcc 4.5.0 (tdm-1)\\
|
1559
1582
|
\begin{tabular}{|l|l|r|r|r|r|}
|
1560
1583
|
\hline
|
1561
1584
|
GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\
|
1562
1585
|
\hline
|
1563
|
-
4.3.2 & multiply &
|
1564
|
-
& divide &
|
1565
|
-
& gcd &
|
1566
|
-
& rsa &
|
1586
|
+
4.3.2 & multiply & 3607.9 & 3679.3 & 3655.5 & 6448.7 \\
|
1587
|
+
& divide & 3062.6 & 3103.7 & 3074.5 & 3717.5 \\
|
1588
|
+
& gcd & 1165 & 1190.6 & 1211.8 & 1359.4 \\
|
1589
|
+
& rsa & 733.87 & 729.9 & 742.22 & 757.97 \\
|
1567
1590
|
\hline
|
1568
|
-
5.0.1 & multiply &
|
1569
|
-
& divide &
|
1570
|
-
& gcd &
|
1571
|
-
& rsa &
|
1591
|
+
5.0.1 & multiply & 3792.1 & 3869 & 3785.9 & 6835.2 \\
|
1592
|
+
& divide & 4662.2 & 4704.4 & 4692.3 & 6497.4 \\
|
1593
|
+
& gcd & 1222.8 & 1249.7 & 1245 & 1394.2 \\
|
1594
|
+
& rsa & 742.78 & 745.66 & 739.9 & 754.72 \\
|
1572
1595
|
\hline
|
1573
1596
|
\end{tabular}\\
|
1574
1597
|
|
1575
|
-
\end{document}
|
1598
|
+
\end{document}
|