gmp 0.5.23 → 0.5.41

Sign up to get free protection for your applications and to get access to all the features.
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.fac(4) #=> 3
1616
- * * GMP::Z.fac(5) #=> 5
1617
- * * GMP::Z.fac(6) #=> 8
1618
- * * GMP::Z.fac(7) #=> 13
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);
@@ -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
- #if SIZEOF_INT < SIZEOF_LONG
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.23}}\\
38
- \multicolumn{2}{r}{\large{04 October 2010}}
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 started to poke
152
- around with REE. Everything seems to work on REE 1.8.7 on Linux, x86 and x86\_64.\\
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 & GMP & (MPFR) \\ \midrule[1pt]
178
- Linux (Ubuntu NR 10.04) on x86 (32-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
179
- & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
180
- & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
181
- & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
182
- & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
183
- & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
184
- Linux (Ubuntu 10.04) on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
185
- & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
186
- & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
187
- & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
188
- & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
189
- & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
190
- Mac OS X 10.6.4 on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
191
- & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
192
- & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
193
- & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
194
- & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
195
- & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
196
- Windows 7 on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
197
- & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
198
- & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
199
- & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
200
- & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
201
- & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
202
- Windows XP on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
203
- & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ \hline
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 & 7696.5 & 7482.8 & 7608.2 & 16789 \\
1528
- & divide & 7304.3 & 7148.0 & 7199.4 & 9872.5 \\
1529
- & gcd & 2388.4 & 2412.1 & 2470.9 & 2938.9 \\
1530
- & rsa & 2042.3 & 2058.0 & 2065.9 & 2136.7 \\
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 & 8142.6 & 7886.0 & 7952.7 & 17925 \\
1533
- & divide & 10256 & 10088 & 10124 & 16069 \\
1534
- & gcd & 2498.1 & 2547.0 & 2574.2 & 3063.7 \\
1535
- & rsa & 2132.4 & 2157.4 & 2167.9 & 2229.2 \\
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-24, x86\_64 (64-bit)\\
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{tabular}{|l|l|r|r|r|r|}
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 & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\
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 & 7793.7 & 6825.7 & 7460.6 & 14716 \\
1546
- & divide & 7687.6 & 7725.9 & 7473.3 & 8614.3 \\
1547
- & gcd & 2450.1 & 2507.6 & 2476.6 & 2779.8 \\
1548
- & rsa & 1979.1 & 2065.6 & 2059.2 & 1984.3 \\
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 & 9727.1 & 7020.3 & 7902.1 & 17695 \\
1551
- & divide & 9306.4 & 10785 & 10799 & 15629 \\
1552
- & gcd & 2345.3 & 2525.5 & 2541.2 & 2925.1 \\
1553
- & rsa & 2116.5 & 2117.8 & 2143.9 & 2233.4 \\
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 & 3514.7 & 3649.4 & 3631.9 & 6448.7 \\
1564
- & divide & 2996.7 & 3082.0 & 3065.2 & 3717.5 \\
1565
- & gcd & 1142.8 & 1183.3 & 1203.6 & 1359.4 \\
1566
- & rsa & 719.41 & 730.05 & 736.03 & 757.97 \\
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 & 3702.9 & 3824.1 & 3763.8 & 6835.2 \\
1569
- & divide & 4549.7 & 4600.9 & 4609.2 & 6497.4 \\
1570
- & gcd & 1204.9 & 1233.4 & 1235.0 & 1394.2 \\
1571
- & rsa & 729.68 & 735.13 & 728.56 & 754.72 \\
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}