gmp 0.4.7 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -21,27 +21,38 @@ VALUE r_mprnd_initialize(int argc, VALUE *argv, VALUE self)
21
21
  VALUE mode, name, ieee754;
22
22
  mode = argv[0];
23
23
  (void)argc;
24
+ const char *prefix;
25
+ char name_val[10];
26
+ if (MPFR_VERSION_MAJOR < 3)
27
+ prefix = "GMP";
28
+ else
29
+ prefix = "MPFR";
24
30
  switch (FIX2INT(mode)) {
25
31
  case 0:
26
- name = rb_str_new2("GMP_RNDN");
32
+ sprintf(name_val, "%s_RNDN", prefix);
27
33
  ieee754 = rb_str_new2("roundTiesToEven");
28
34
  break;
29
35
  case 1:
30
- name = rb_str_new2("GMP_RNDZ");
36
+ sprintf(name_val, "%s_RNDZ", prefix);
31
37
  ieee754 = rb_str_new2("roundTowardZero");
32
38
  break;
33
39
  case 2:
34
- name = rb_str_new2("GMP_RNDU");
40
+ sprintf(name_val, "%s_RNDU", prefix);
35
41
  ieee754 = rb_str_new2("roundTowardPositive");
36
42
  break;
37
43
  case 3:
38
- name = rb_str_new2("GMP_RNDD");
44
+ sprintf(name_val, "%s_RNDD", prefix);
39
45
  ieee754 = rb_str_new2("roundTowardNegative");
40
46
  break;
47
+ case 4:
48
+ sprintf(name_val, "%s_RNDA", prefix);
49
+ ieee754 = rb_str_new2("roundAwayFromZero");
50
+ break;
41
51
  default:
42
- name = rb_str_new2("GMP_RNDN");
52
+ sprintf(name_val, "%s_RNDN", prefix);
43
53
  ieee754 = rb_str_new2("roundTiesToEven");
44
54
  }
55
+ name = rb_str_new2(name_val);
45
56
  rb_iv_set(self, "@mode", mode);
46
57
  rb_iv_set(self, "@name", name);
47
58
  rb_iv_set(self, "@ieee754", ieee754);
@@ -72,6 +83,13 @@ void init_gmprnd()
72
83
  rb_define_const(mGMP, "GMP_RNDZ", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(1)));
73
84
  rb_define_const(mGMP, "GMP_RNDU", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(2)));
74
85
  rb_define_const(mGMP, "GMP_RNDD", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(3)));
86
+ /* MPFR 3.0.0 */
87
+ rb_define_const(mGMP, "MPFR_RNDN", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(0)));
88
+ rb_define_const(mGMP, "MPFR_RNDZ", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(1)));
89
+ rb_define_const(mGMP, "MPFR_RNDU", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(2)));
90
+ rb_define_const(mGMP, "MPFR_RNDD", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(3)));
91
+ rb_define_const(mGMP, "MPFR_RNDA", rb_funcall (cGMP_Rnd, new_id, 1, INT2FIX(4)));
92
+ /* end MPFR 3.0.0 */
75
93
  }
76
94
 
77
95
  #endif /* MPFR */
@@ -40,38 +40,90 @@ typedef __mpf_struct MP_FLOAT;
40
40
  */
41
41
  typedef __gmp_randstate_struct MP_RANDSTATE;
42
42
 
43
+ /*
44
+ * Here, MPFR is not included, so we are pure GMP. In GMP, mpf_get_prec returns
45
+ * an unsigned long int, so we will too.
46
+ */
47
+ #ifndef MPFR
48
+ typedef unsigned long mpfr_prec_t;
49
+ /*
50
+ * Here, MPFR is not included, so we are pure GMP. In GMP, mpf_get_prec returns
51
+ * an unsigned long int, so we will too.
52
+ */
53
+ #endif
54
+
43
55
  #define mpz_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_INT, c_var); }
44
56
  #define mpq_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_RAT, c_var); }
45
57
  #define mpf_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_FLOAT, c_var); }
46
58
  #define mprandstate_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_RANDSTATE, c_var); }
47
- #define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpf_get_prec(c_var); }
48
59
  #define mpz_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Z, MP_INT, 0, r_gmpz_free, c_var); }
49
60
  #define mpq_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Q, MP_RAT, 0, r_gmpq_free, c_var); }
50
61
  #define mpf_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_F, MP_FLOAT, 0, r_gmpf_free, c_var); }
51
62
  #define mprandstate_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_RandState, MP_RANDSTATE, 0, r_gmprandstate_free, c_var); }
52
63
  #define mpz_make_struct_init(ruby_var,c_var) { mpz_make_struct(ruby_var,c_var); mpz_init (c_var); }
53
64
  #define mpq_make_struct_init(ruby_var,c_var) { mpq_make_struct(ruby_var,c_var); mpq_init (c_var); }
54
- #define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpf_init2 (c_var,prec); }
55
65
  #define BIGNUM_P(value) (TYPE(value) == T_BIGNUM)
56
66
  #define FLOAT_P(value) (TYPE(value) == T_FLOAT)
57
67
  #define STRING_P(value) (TYPE(value) == T_STRING)
58
68
  #define GMPZ_P(value) (rb_obj_is_instance_of(value, cGMP_Z) == Qtrue)
59
69
  #define GMPQ_P(value) (rb_obj_is_instance_of(value, cGMP_Q) == Qtrue)
60
70
  #define GMPF_P(value) (rb_obj_is_instance_of(value, cGMP_F) == Qtrue)
61
- #define mpz_set_bignum(var_mpz,var_bignum) \
62
- mpz_set_str (var_mpz, STR2CSTR (rb_funcall (var_bignum, rb_intern ("to_s"), 0)), 0);
71
+ #define mpz_set_bignum(var_mpz,var_bignum) { \
72
+ VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"), 0); \
73
+ mpz_set_str (var_mpz, StringValuePtr (tmp), 0); \
74
+ }
63
75
  #define mpz_temp_alloc(var) { var=malloc(sizeof(MP_INT)); }
64
76
  #define mpz_temp_init(var) { mpz_temp_alloc(var); mpz_init(var); }
65
- #define mpz_temp_from_bignum(var,var_bignum) \
66
- { mpz_temp_alloc(var); mpz_init_set_str(var, STR2CSTR(rb_funcall(var_bignum, rb_intern("to_s"), 0)), 0); }
77
+ #define mpz_temp_from_bignum(var,var_bignum) { \
78
+ mpz_temp_alloc(var); \
79
+ VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"), 0); \
80
+ mpz_init_set_str (var, StringValuePtr (tmp), 0); \
81
+ }
67
82
  #define mpz_temp_free(var) { mpz_clear(var); free(var); }
68
83
  #define mpf_temp_alloc(var) { var=malloc(sizeof(MP_FLOAT)); }
84
+ #if defined(MPFR) && defined(HAVE_MPFR_H)
85
+ #define prec_max(prec,var) {if(mpfr_get_prec(var) > prec) prec = mpfr_get_prec(var); }
86
+ #else
87
+ #define prec_max(prec,var) {if(mpf_get_prec(var) > prec) prec = mpf_get_prec(var); }
88
+ #endif
89
+
90
+ #if defined(MPFR) && defined(HAVE_MPFR_H)
91
+ #define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpfr_get_prec(c_var); }
92
+ #define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpfr_init2 (c_var,prec); }
93
+ #define mpf_temp_init(var,prec) { mpf_temp_alloc(var); mpfr_init2(var,prec); }
94
+ #define mpf_temp_free(var) { mpfr_clear(var); free(var); }
95
+ #define r_mpf_init(var1) (mpfr_init(var1))
96
+ #define r_mpf_init2(var1, var2) (mpfr_init2(var1, var2))
97
+ #define r_mpf_set_z(var1, var2) (mpfr_set_z(var1, var2, __gmp_default_rounding_mode))
98
+ #define r_mpf_set_q(var1, var2) (mpfr_set_q(var1, var2, __gmp_default_rounding_mode))
99
+ #define r_mpf_set_d(var1, var2) (mpfr_set_d(var1, var2, __gmp_default_rounding_mode))
100
+ #define r_mpf_set_str(var1, var2, var3) (mpfr_set_str(var1, var2, var3, __gmp_default_rounding_mode))
101
+ #define r_mpf_cmp(var1, var2) (mpfr_cmp(var1, var2))
102
+ #else
103
+ #define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpf_get_prec(c_var); }
104
+ #define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpf_init2 (c_var,prec); }
69
105
  #define mpf_temp_init(var,prec) { mpf_temp_alloc(var); mpf_init2(var,prec); }
70
106
  #define mpf_temp_free(var) { mpf_clear(var); free(var); }
71
- #define prec_max(prec,var) {if(mpf_get_prec(var) > prec) prec = mpf_get_prec(var); }
107
+ #define r_mpf_init(var1) (mpf_init(var1))
108
+ #define r_mpf_init2(var1, var2) (mpf_init2(var1, var2))
109
+ #define r_mpf_set_z(var1, var2) (mpf_set_z(var1, var2))
110
+ #define r_mpf_set_q(var1, var2) (mpf_set_q(var1, var2))
111
+ #define r_mpf_set_d(var1, var2) (mpf_set_d(var1, var2))
112
+ #define r_mpf_set_str(var1, var2, var3) (mpf_set_str(var1, var2, var3))
113
+ #define r_mpf_cmp(var1, var2) (mpf_cmp(var1, var2))
114
+ #endif
115
+
116
+ #if SIZEOF_INT < SIZEOF_LONG
117
+ /* 64-bit */
118
+ #define FIX2NUM(x) FIX2LONG(x)
119
+ #else
120
+ /* 32-bit */
121
+ #define FIX2NUM(x) FIX2INT(x)
122
+ #endif
72
123
 
73
124
  #define EXPECTED_ZQFXBD "Expected GMP::Z, GMP::Q, GMP::F, Fixnum, Bignum or Float"
74
125
  #define EXPECTED_ZQFXB "Expected GMP::Z, GMP::Q, GMP::F, Fixnum or Bignum"
126
+ #define EXPECTED_ZFXBD "Expected GMP::Z, GMP::F, Fixnum, Bignum or Float"
75
127
  #define EXPECTED_ZXB "Expected GMP::Z, Fixnum or Bignum"
76
128
  #define EXPECTED_ZX "Expected GMP::Z or Fixnum"
77
129
  #define EXPECTED_X "Expected Fixnum"
@@ -201,15 +253,23 @@ extern VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass);
201
253
  extern VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self);
202
254
  extern void mpf_set_value(MP_FLOAT *self_val, VALUE arg);
203
255
  extern VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module);
256
+ extern VALUE r_gmpf_get_prec(VALUE self);
257
+ extern VALUE r_gmpf_set_prec(VALUE self, VALUE arg);
258
+ extern VALUE r_gmpf_set_prec_raw(VALUE self, VALUE arg);
204
259
 
205
260
  // Converting Floats
206
261
  extern VALUE r_gmpf_to_d(VALUE self);
207
262
  extern VALUE r_gmpf_to_s(VALUE self);
208
263
 
209
264
  // Float Arithmetic
265
+ #ifndef MPFR
210
266
  extern VALUE r_gmpf_add(VALUE self, VALUE arg);
211
- extern VALUE r_gmpf_sub(VALUE self, VALUE arg);
212
267
  extern VALUE r_gmpf_mul(VALUE self, VALUE arg);
268
+ #else
269
+ extern VALUE r_gmpfr_add(int argc, VALUE *argv, VALUE self);
270
+ extern VALUE r_gmpfr_mul(int argc, VALUE *argv, VALUE self);
271
+ #endif
272
+ extern VALUE r_gmpf_sub(VALUE self, VALUE arg);
213
273
  extern VALUE r_gmpf_div(VALUE self, VALUE arg);
214
274
 
215
275
  // Float Comparison
@@ -219,7 +279,11 @@ extern int mpf_cmp_value(MP_FLOAT *OP, VALUE arg);
219
279
 
220
280
  // MPFR
221
281
  #ifdef MPFR
282
+ extern void mpf_set_value2(MP_FLOAT *self_val, VALUE arg, int base);
283
+
222
284
  extern VALUE r_gmpfr_sqrt(int argc, VALUE *argv, VALUE self);
285
+ extern VALUE r_gmpfr_rec_sqrt(int argc, VALUE *argv, VALUE self);
286
+ extern VALUE r_gmpfr_cbrt(int argc, VALUE *argv, VALUE self);
223
287
 
224
288
  extern VALUE r_gmpfr_log(int argc, VALUE *argv, VALUE self);
225
289
  extern VALUE r_gmpfr_log2(int argc, VALUE *argv, VALUE self);
@@ -256,6 +320,9 @@ extern int mpf_cmp_value(MP_FLOAT *OP, VALUE arg);
256
320
  extern VALUE r_gmpfr_gamma(int argc, VALUE *argv, VALUE self);
257
321
  extern VALUE r_gmpfr_lngamma(int argc, VALUE *argv, VALUE self);
258
322
  /*extern VALUE r_gmpfr_lgamma(int argc, VALUE *argv, VALUE self);*/
323
+ #if MPFR_VERSION_MAJOR > 2
324
+ extern VALUE r_gmpfr_digamma(int argc, VALUE *argv, VALUE self);
325
+ #endif
259
326
  extern VALUE r_gmpfr_zeta(int argc, VALUE *argv, VALUE self);
260
327
  extern VALUE r_gmpfr_erf(int argc, VALUE *argv, VALUE self);
261
328
  extern VALUE r_gmpfr_erfc(int argc, VALUE *argv, VALUE self);
@@ -275,7 +342,6 @@ extern int mpf_cmp_value(MP_FLOAT *OP, VALUE arg);
275
342
 
276
343
  // _unsorted_
277
344
  extern VALUE r_gmpf_sgn(VALUE self);
278
- extern VALUE r_gmpf_get_prec(VALUE self);
279
345
 
280
346
 
281
347
  /* from gmprandstate.h */
@@ -0,0 +1,9 @@
1
+ # Thank you, Nokogiri
2
+
3
+ require 'rbconfig'
4
+
5
+ ENV['PATH'] = [File.expand_path(
6
+ File.join(File.dirname(__FILE__), "..", "ext")
7
+ ), ENV['PATH']].compact.join(';') if RbConfig::CONFIG['host_os'] =~ /(mswin|mingw|mingw32)/i
8
+
9
+ require File.dirname(__FILE__) + '/../ext/gmp'
data/manual.pdf CHANGED
Binary file
data/manual.tex CHANGED
@@ -20,7 +20,13 @@
20
20
  \def\qqqquad{\quad\quad\quad\quad}
21
21
  \def\cc{\colon\colon}
22
22
  \def\gmpz{\textit{GMP::Z}}
23
- \def\gmprandstate{\textit{GMP::RandState\ }}
23
+ \def\gmpq{\textit{GMP::Q}}
24
+ \def\gmpf{\textit{GMP::F}}
25
+ \def\gmprandstate{\textit{GMP::RandState}}
26
+ \def\gmpzs{\textit{GMP::Z}\ }
27
+ \def\gmpqs{\textit{GMP::Q}\ }
28
+ \def\gmpfs{\textit{GMP::F}\ }
29
+ \def\gmprandstates{\textit{GMP::RandState\ }}
24
30
  \frenchspacing
25
31
  \begin{document}
26
32
 
@@ -28,8 +34,8 @@
28
34
  \huge{gmp} &\\
29
35
  \midrule[3pt]
30
36
  \multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\
31
- \multicolumn{2}{r}{\large{Edition 0.4.7}}\\
32
- \multicolumn{2}{r}{\large{25 March 2010}}
37
+ \multicolumn{2}{r}{\large{Edition 0.5.3}}\\
38
+ \multicolumn{2}{r}{\large{20 September 2010}}
33
39
  \end{tabular}
34
40
 
35
41
  \vfill
@@ -76,37 +82,59 @@ SPARCv7, SuperSPARC, generic SPARCv8, UltraSPARC, DEC VAX, and Zilog Z8000.
76
82
  Some optimizations also for Cray vector systems, Clipper, IBM ROMP (RT), and
77
83
  Pyramid AP/XP.\\
78
84
  \\
79
- For up-to-date information on GMP, please see the GMP web pages at\\
80
- \setlength{\parindent}{0.25in}
81
- \texttt{http://gmplib.org/}
82
- \setlength{\parindent}{0in}
83
- \\
85
+ For up-to-date information on GMP, please see the GMP web pages at
86
+ \url{http://gmplib.org/}\\
84
87
 
85
- The latest version of the library is available at\\
86
- \setlength{\parindent}{0.25in}
87
- \texttt{ftp://ftp.gnu.org/gnu/gmp/}\\
88
- \setlength{\parindent}{0in}
89
- \\
88
+ The latest version of the library is available at
89
+ \url{ftp://ftp.gnu.org/gnu/gmp/}\\
90
90
 
91
- Many sites around the world mirror '\texttt{ftp.gnu.org}', please use a mirror
92
- near you, see \texttt{http://www.gnu.org/order/ftp.html} for a full list.\\
91
+ Many sites around the world mirror '\url{ftp.gnu.org}', please use a mirror
92
+ near you, see \url{http://www.gnu.org/order/ftp.html} for a full list.\\
93
93
  \\
94
94
  There are three public mailing lists of interest. One for release
95
95
  announcements, one for general questions and discussions about usage of the GMP
96
- library, and one for bug reports. For more information, see\\
97
- \\
98
- \texttt{http://gmplib.org/mailman/listinfo/}.\\
99
- \\
96
+ library, and one for bug reports. For more information, see
97
+ \url{http://gmplib.org/mailman/listinfo/}.\\
98
+
100
99
  The proper place for bug reports is gmp-bugs@gmplib.org. See Chapter 4
101
100
  [Reporting Bugs], page 28 for information about reporting bugs.
102
101
 
102
+ \newpage
103
+ \section{Introduction to MPFR}
104
+
105
+ The gmp gem optionally interacts with the MPFR library as well. This entire page
106
+ is copied verbatim from the MPFR manual.\\\\
107
+
108
+ The MPFR library is a C library for multiple-precision floating-point
109
+ computations with correct rounding. MPFR has continuously been supported by the
110
+ INRIA and the current main authors come from the Caramel and Ar�naire
111
+ project-teams at Loria (Nancy, France) and LIP (Lyon, France) respectively; see
112
+ more on the credit page. MPFR is based on the GMP multiple-precision library.\\
113
+
114
+ The main goal of MPFR is to provide a library for multiple-precision
115
+ floating-point computation which is both efficient and has a well-defined
116
+ semantics. It copies the good ideas from the ANSI/IEEE-754 standard for
117
+ double-precision floating-point arithmetic (53-bit mantissa).\\
118
+
119
+ MPFR is free. It is distributed under the GNU Lesser General Public License
120
+ (GNU Lesser GPL), version 3 or later (2.1 or later for MPFR versions until
121
+ 2.4.x). The library has been registered in France by the Agence de Protection
122
+ des Programmes under the number IDDN FR 001 120020 00 R P 2000 000 10800, on 15
123
+ March 2000. This license guarantees your freedom to share and change MPFR, to
124
+ make sure MPFR is free for all its users. Unlike the ordinary General Public
125
+ License, the Lesser GPL enables developers of non-free programs to use MPFR in
126
+ their programs. If you have written a new function for MPFR or improved an
127
+ existing one, please share your work!
128
+
129
+ \newpage
103
130
  \section{Introduction to the gmp gem}
104
131
 
105
132
  The gmp Ruby gem is a Ruby library that provides bindings to GMP. The gem is
106
133
  incomplete, and will likely only include a subset of the GMP functions. It is
107
- built as a C extension for ruby, interacting with gmp.h. The gmp gem is not
108
- endorsed or supported by GNU or the GMP team. The gmp gem also does not ship
109
- with GMP, so GMP must be compiled separately.
134
+ built as a C extension for Ruby, interacting with gmp.h. The gmp gem is not
135
+ endorsed or supported by GNU or the GMP team (or MPFR team). The gmp gem also
136
+ does not ship with GMP (or MPFR), so GMP (and MPFR) must be compiled
137
+ separately.
110
138
 
111
139
  \section{Installing the gmp gem}
112
140
 
@@ -117,6 +145,7 @@ of the following versions of Ruby:
117
145
  \item (MRI) Ruby 1.8.6 - tested lightly.
118
146
  \item (MRI) Ruby 1.8.7 - tested seriously.
119
147
  \item (MRI) Ruby 1.9.1 - tested seriously.
148
+ \item (MRI) Ruby 1.9.2 - tested seriously.
120
149
  \end{itemize}
121
150
  As you can see only Matz's Ruby Interpreter (MRI) is supported. I haven't even
122
151
  put a thought into trying other interpreters/VMs. I intend to look into FFI,
@@ -124,22 +153,53 @@ which supposedly will allow me to load this extension into JRuby and Rubinius,
124
153
  not sure about others...\\
125
154
 
126
155
  Next is the platform, the combination of the architecture (processor) and OS.
127
- As far as I can tell, if you can compile GMP and Ruby on a given platform, you
128
- can use the gmp gem there too. Please report problems with that hypothesis.\\
156
+ As far as I can tell, if you can compile GMP and Ruby (and optionally MPFR) on
157
+ a given platform, you can use the gmp gem there too. Please report problems
158
+ with that hypothesis.\\
129
159
 
130
- Lastly, GMP. GMP must be compiled and working. "and working" means you ran "make
131
- check" while installing GMP. The following versions of GMP have been tested:
160
+ Lastly, GMP (and MPFR). GMP (and MPFR) must be compiled and working. "And working" means
161
+ you ran "make check" after compiling GMP (and MPFR), and it 'check's out. The following
162
+ versions of GMP (and MPFR) have been tested:
132
163
  \begin{itemize}
133
- \item GMP 4.3.1
134
- \item GMP 4.3.2
135
- \item GMP 5.0.0
136
- \item GMP 5.0.1
164
+ \item GMP 4.3.1 (with MPFR 2.4.2)
165
+ \item GMP 4.3.2 (with MPFR 2.4.2 and 3.0.0)
166
+ \item GMP 5.0.0 (with MPFR 3.0.0)
167
+ \item GMP 5.0.1 (with MPFR 3.0.0)
137
168
  \end{itemize}
138
169
 
139
- That's all. I don't intend to test any older versions, maybe 4.3.0 for
140
- completeness.\\
170
+ That's all. I don't intend to test any older versions.\\
141
171
 
142
- Here is a table of the exact environments on which I have tested the gmp gem:\\\\
172
+ \newpage
173
+ Here is a table of the exact environments on which I have tested the gmp gem.
174
+ The (MPFR) version denotes that the gmp gem was tested both with and without
175
+ the given version of MPFR:\\\\
176
+
177
+ \begin{tabular}{lrrr} \hline
178
+ Platform & Ruby & GMP & (MPFR) \\ \midrule[1pt]
179
+ Linux (Ubuntu NR 10.04) on x86 (32-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
180
+ & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
181
+ & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
182
+ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
183
+ & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
184
+ & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
185
+ Linux (Ubuntu 10.04) on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
186
+ & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
187
+ & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
188
+ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
189
+ & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
190
+ & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
191
+ Mac OS X 10.6.4 on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
192
+ & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
193
+ & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
194
+ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
195
+ & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
196
+ & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
197
+ Windows XP on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
198
+ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ \hline
199
+ \end{tabular}\\\\
200
+
201
+ In addition, I \textit{used to test} on the following environments, in versions
202
+ 0.4.7 and earlier of the gmp gem:\\\\
143
203
 
144
204
  \begin{tabular}{lrr} \hline
145
205
  Platform & Ruby & GMP \\ \midrule[1pt]
@@ -147,7 +207,6 @@ Here is a table of the exact environments on which I have tested the gmp gem:\\\
147
207
  Linux (LinuxMint 7) on x86 & (MRI) Ruby 1.8.7 & GMP 4.3.1 \\ \hline
148
208
  Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.8.6 & GMP 4.3.1 \\ \hline
149
209
  Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.1 \\ \hline
150
- Windows XP on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 5.0.1 \\ \hline
151
210
  \end{tabular}
152
211
 
153
212
  \subsection{Installing}
@@ -155,11 +214,12 @@ You may clone the gmp gem's git repository with:\\
155
214
  \\
156
215
  \texttt{git clone git://github.com/srawlins/gmp.git}\\
157
216
 
158
- Or you may install the gem from gemcutter:\\
217
+ Or you may install the gem from gemcutter (rubygems.org):\\
159
218
  \\
160
219
  \texttt{gem install gmp}\\
161
220
 
162
- At this time, the gem does self-compiles. If required libraries cannot be found, you may
221
+ \newpage
222
+ At this time, the gem self-compiles. If required libraries cannot be found, you may
163
223
  compile the C extensions manually with:\\
164
224
  \\
165
225
  \texttt{cd <gmp gem directory>/ext}\\
@@ -177,7 +237,12 @@ You can run this test suite with:\\
177
237
  \texttt{ruby unit\_tests.rb}\\
178
238
 
179
239
  All tests should pass. If you don't have the test-unit gem installed, then you may
180
- run into one error.
240
+ run into one error. It would look like:\\
241
+ \\
242
+ \texttt{ 1) Error:}\\
243
+ \texttt{test\_z\_div(TC\_division):}\\
244
+ \texttt{TypeError: GMP::Q can't be coerced into Float}\\
245
+ \texttt{ C:/Ruby191/devkit/msys/1.0.11/projects/gmp\_gem/test/tc\_division.rb:18:in `test\_z\_div'}\\
181
246
 
182
247
  \section{GMP and gmp gem basics}
183
248
 
@@ -219,6 +284,18 @@ There are additional constants within \texttt{GMP} when MPFR is linked:
219
284
  infinity."
220
285
  \item \texttt{GMP::GMP\_RNDD} - Rounding mode representing "round toward negative
221
286
  infinity."
287
+ \item \texttt{GMP::MPFR\_RNDN} - Rounding mode representing "round to nearest."\\
288
+ (MPFR version 3.0.0 or higher only)
289
+ \item \texttt{GMP::MPFR\_RNDZ} - Rounding mode representing "round toward zero."\\
290
+ (MPFR version 3.0.0 or higher only)
291
+ \item \texttt{GMP::MPFR\_RNDU} - Rounding mode representing "round toward positive
292
+ infinity."\\
293
+ (MPFR version 3.0.0 or higher only)
294
+ \item \texttt{GMP::MPFR\_RNDD} - Rounding mode representing "round toward negative
295
+ infinity."\\
296
+ (MPFR version 3.0.0 or higher only)
297
+ \item \texttt{GMP::MPFR\_RNDZ} - Rounding mode representing "round away from zero."\\
298
+ (MPFR version 3.0.0 or higher only)
222
299
  \end{itemize}
223
300
 
224
301
  \newpage
@@ -233,8 +310,8 @@ There are additional constants within \texttt{GMP} when MPFR is linked:
233
310
  & & GMP::Z.new(\textit{str}) $\rightarrow$ \textit{integer} \\
234
311
  \cmidrule(r){2-3}
235
312
  & \multicolumn{2}{p{\defnwidth}}{
236
- This method creates a new \textit{GMP::Z} integer. It takes one optional argument for
237
- the value of the integer. This argument can be one of several classes. Here are some
313
+ This method creates a new \gmpzs integer. It takes one optional argument for the value
314
+ of the integer. This argument can be one of several classes. Here are some
238
315
  examples:\newline
239
316
 
240
317
  \texttt{GMP::Z.new \qqqquad\qqqquad \#=> 0 (default) \newline
@@ -279,8 +356,8 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
279
356
  \textit{integer}.
280
357
  \newline
281
358
 
282
- If \textit{integer} is too big to fit in a Fixnum, the returned result is probably not
283
- very useful. To find out if the value will fit, use the function
359
+ If \textit{integer} is too big to fit in a \textit{Fixnum}, the returned result is
360
+ probably not very useful. To find out if the value will fit, use the function
284
361
  \textit{mpz\_fits\_slong\_p} (\textbf{Unimplemented}).
285
362
  }
286
363
  \end{tabular}
@@ -322,8 +399,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
322
399
  \cmidrule(r){2-3}
323
400
  & \multicolumn{2}{p{\defnwidth}}{
324
401
  Returns the sum of \textit{integer} and \textit{numeric}. \textit{numeric} can be an
325
- instance of \textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or
326
- \textit{Bignum}.
402
+ instance of \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}.
327
403
  }
328
404
  \end{tabular}
329
405
  \newline\newline
@@ -335,8 +411,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
335
411
  \cmidrule(r){2-3}
336
412
  & \multicolumn{2}{p{\defnwidth}}{
337
413
  Sums \textit{integer} and \textit{numeric}, in place. \textit{numeric} can be an
338
- instance of \textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or
339
- \textit{Bignum}.
414
+ instance of \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}.
340
415
  }
341
416
  \end{tabular}
342
417
  \newline\newline
@@ -349,8 +424,8 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
349
424
  & \multicolumn{2}{p{\defnwidth}}{
350
425
  Returns the difference of \textit{integer} and \textit{numeric}. The destructive method
351
426
  calculates the difference in place. \textit{numeric} can be an instance of
352
- \textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or \textit{Bignum}.
353
- Here are some examples:\newline
427
+ \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}. Here are some
428
+ examples:\newline
354
429
 
355
430
  \texttt{seven = GMP::Z(7) \newline
356
431
  nine \ = GMP::Z(9) \newline
@@ -376,7 +451,19 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
376
451
  & \multicolumn{2}{p{\defnwidth}}{
377
452
  Returns the product of \textit{integer} and \textit{numeric}. The destructive method
378
453
  calculates the product in place. \textit{numeric} can be an instance of
379
- \textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or \textit{Bignum}.
454
+ \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}.
455
+ }
456
+ \end{tabular}
457
+ \newline\newline
458
+
459
+ \begin{tabular}{p{\methwidth} l r}
460
+ \toprule
461
+ \textbf{addmul!} & & \textit{integer}.addmul!(\textit{a}, \textit{b}) $\rightarrow$ \textit{numeric} \\
462
+ \cmidrule(r){2-3}
463
+ & \multicolumn{2}{p{\defnwidth}}{
464
+ Sets \textit{integer} to the sum of \textit{integer} and the product of \textit{a} and
465
+ \textit{b}. This destructive method calculates the result in place. Both \textit{a} and
466
+ \textit{b} can be an instance of \gmpz, \textit{Fixnum}, or \textit{Bignum}.
380
467
  }
381
468
  \end{tabular}
382
469
  \newline\newline
@@ -424,7 +511,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
424
511
  \cmidrule(r){2-3}
425
512
  & \multicolumn{2}{p{\defnwidth}}{
426
513
  Returns the division of $integer$ by $numeric$, truncated. $numeric$ can be an instance
427
- of $GMP::Z$, $Fixnum$, $Bignum$. The return object's class is always $GMP::Z$.
514
+ of \gmpz, $Fixnum$, $Bignum$. The return object's class is always \gmpz.
428
515
  }
429
516
  \end{tabular}
430
517
  \newline\newline
@@ -435,7 +522,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
435
522
  \cmidrule(r){2-3}
436
523
  & \multicolumn{2}{p{\defnwidth}}{
437
524
  Returns the division of $integer$ by $numeric$, floored. $numeric$ can be an instance
438
- of $GMP::Z$, $Fixnum$, $Bignum$. The return object's class is always $GMP::Z$.
525
+ of \gmpz, $Fixnum$, $Bignum$. The return object's class is always \gmpz.
439
526
  }
440
527
  \end{tabular}
441
528
  \newline\newline
@@ -446,7 +533,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
446
533
  \cmidrule(r){2-3}
447
534
  & \multicolumn{2}{p{\defnwidth}}{
448
535
  Returns the ceiling division of $integer$ by $numeric$. $numeric$ can be an instance of
449
- $GMP::Z$, $Fixnum$, $Bignum$. The return object's class is always $GMP::Z$.
536
+ \gmpz, $Fixnum$, $Bignum$. The return object's class is always \gmpz.
450
537
  }
451
538
  \end{tabular}
452
539
  \newline\newline
@@ -457,8 +544,8 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
457
544
  \cmidrule(r){2-3}
458
545
  & \multicolumn{2}{p{\defnwidth}}{
459
546
  Returns the remainder after truncated division of $integer$ by $numeric$. $numeric$ can
460
- be an instance of $GMP::Z$, $Fixnum$, or $Bignum$. The return object's class is always
461
- $GMP::Z$.
547
+ be an instance of \gmpz, $Fixnum$, or $Bignum$. The return object's class is always
548
+ \gmpz.
462
549
  }
463
550
  \end{tabular}
464
551
  \newline\newline
@@ -469,8 +556,8 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
469
556
  \cmidrule(r){2-3}
470
557
  & \multicolumn{2}{p{\defnwidth}}{
471
558
  Returns the remainder after floored division of $integer$ by $numeric$. $numeric$ can
472
- be an instance of $GMP::Z$, $Fixnum$, or $Bignum$. The return object's class is always
473
- $GMP::Z$.
559
+ be an instance of \gmpz, $Fixnum$, or $Bignum$. The return object's class is always
560
+ \gmpz.
474
561
  }
475
562
  \end{tabular}
476
563
  \newline\newline
@@ -481,8 +568,8 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
481
568
  \cmidrule(r){2-3}
482
569
  & \multicolumn{2}{p{\defnwidth}}{
483
570
  Returns the remainder after ceilinged division of $integer$ by $numeric$. $numeric$ can
484
- be an instance of $GMP::Z$, $Fixnum$, or $Bignum$. The return object's class is always
485
- $GMP::Z$.
571
+ be an instance of \gmpz, $Fixnum$, or $Bignum$. The return object's class is always
572
+ \gmpz.
486
573
  }
487
574
  \end{tabular}
488
575
  \newline\newline
@@ -504,9 +591,11 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
504
591
  \toprule
505
592
  \textbf{**} & & \textit{integer} ** \textit{numeric} $\rightarrow$ \textit{numeric} \\
506
593
  & & \textit{integer}.pow(\textit{numeric}) $\rightarrow$ \textit{numeric} \\
594
+ & & GMP::Z.pow(\textit{integer}, \textit{numeric}) $\rightarrow$ \textit{numeric} \\
507
595
  \cmidrule(r){2-3}
508
596
  & \multicolumn{2}{p{\defnwidth}}{
509
- Returns $integer$ raised to the $numeric$ power.
597
+ Returns $integer$ raised to the $numeric$ power. In the singleton method (\textit{GMP::Z.pow()}),
598
+ \textit{integer} can be either a \gmpz, $Fixnum$, $Bignum$, or $String$.
510
599
  }
511
600
  \end{tabular}
512
601
  \newline\newline
@@ -814,7 +903,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
814
903
  \textbf{hash} & & $a$.hash $\rightarrow$ $string$ \\
815
904
  \cmidrule(r){2-3}
816
905
  & \multicolumn{2}{p{\defnwidth}}{
817
- Used when comparing objects as Hash keys.
906
+ Used when comparing objects as $Hash$ keys.
818
907
  }
819
908
  \end{tabular}
820
909
 
@@ -967,6 +1056,18 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
967
1056
  }
968
1057
  \end{tabular}
969
1058
 
1059
+ \subsection{Integer Special Functions}
1060
+
1061
+ \begin{tabular}{p{\methwidth} l r}
1062
+ \toprule
1063
+ \textbf{size} & & $integer$.size $\rightarrow$ $fixnum$ \\
1064
+ \cmidrule(r){2-3}
1065
+ & \multicolumn{2}{p{\defnwidth}}{
1066
+ Returns the size of \textit{integer} measured in number of limbs. If \textit{integer}
1067
+ is zero, then the returned value will be zero.
1068
+ }
1069
+ \end{tabular}
1070
+
970
1071
  \newpage
971
1072
  \section{Rational Functions}
972
1073
 
@@ -979,7 +1080,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
979
1080
  & & GMP::Q.new(\textit{str}) $\rightarrow$ \textit{rational} \\
980
1081
  \cmidrule(r){2-3}
981
1082
  & \multicolumn{2}{p{\defnwidth}}{
982
- This method creates a new \textit{GMP::Q} rational number. It takes two optional
1083
+ This method creates a new \gmpq rational number. It takes two optional
983
1084
  arguments for the value of the numerator and denominator. These arguments can each be
984
1085
  an instance of several classes. Here are some
985
1086
  examples:\newline
@@ -1023,6 +1124,242 @@ There is also a convenience method available, \texttt{GMP::Q()}.\\
1023
1124
  }
1024
1125
  \end{tabular}
1025
1126
 
1127
+ \newpage
1128
+ \section{Floating-point Functions}
1129
+
1130
+ \subsection{Initializing, Assigning Floats}
1131
+
1132
+ \subsection{Floating-point Special Functions (MPFR Only)}
1133
+
1134
+ Every method below accepts two additional parameters in addition to any required parameters. These are $rnd_mode$, the rounding mode to use in calculation, which defaults to \textit{GMP::GMP\_RNDN}, and $res_prec$, the precision of the result, which defaults to the \textit{f.prec}, the precision of $f$.\\
1135
+
1136
+ \begin{tabular}{p{\methwidth} l r}
1137
+ \toprule
1138
+ \textbf{log} & & $f$.log(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1139
+ \textbf{log2} & & $f$.log2(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1140
+ \textbf{log10} & & $f$.log10(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1141
+ \cmidrule(r){2-3}
1142
+ & \multicolumn{2}{p{\defnwidth}}{
1143
+ Returns the natural log, $\log_2$, and $\log_10$ of $f$, respectively. Returns $-Inf$ if $f$ is $-0$.
1144
+ }
1145
+ \end{tabular}
1146
+ \newline\newline
1147
+
1148
+ \begin{tabular}{p{\methwidth} l r}
1149
+ \toprule
1150
+ \textbf{exp} & & $f$.exp(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1151
+ \textbf{exp2} & & $f$.exp2(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1152
+ \textbf{exp10} & & $f$.exp10(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1153
+ \cmidrule(r){2-3}
1154
+ & \multicolumn{2}{p{\defnwidth}}{
1155
+ Returns the exponential of $f$, $2$ to the power of $f$, and $10$ to the power of $f$, respectively.
1156
+ }
1157
+ \end{tabular}
1158
+ \newline\newline
1159
+
1160
+ \begin{tabular}{p{\methwidth} l r}
1161
+ \toprule
1162
+ \textbf{cos} & & $f$.cos(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1163
+ \textbf{sin} & & $f$.sin(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1164
+ \textbf{tan} & & $f$.tan(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1165
+ \cmidrule(r){2-3}
1166
+ & \multicolumn{2}{p{\defnwidth}}{
1167
+ Returns the cosine, sine, and tangent of $f$, respectively.
1168
+ }
1169
+ \end{tabular}
1170
+ \newline\newline
1171
+
1172
+ \begin{tabular}{p{\methwidth} l r}
1173
+ \toprule
1174
+ \textbf{sec} & & $f$.sec(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1175
+ \textbf{csc} & & $f$.csc(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1176
+ \textbf{cot} & & $f$.cot(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1177
+ \cmidrule(r){2-3}
1178
+ & \multicolumn{2}{p{\defnwidth}}{
1179
+ Returns the secant, cosecant, and cotangent of $f$, respectively.
1180
+ }
1181
+ \end{tabular}
1182
+ \newline\newline
1183
+
1184
+ \begin{tabular}{p{\methwidth} l r}
1185
+ \toprule
1186
+ \textbf{acos} & & $f$.acos(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1187
+ \textbf{asin} & & $f$.asin(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1188
+ \textbf{atan} & & $f$.atan(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1189
+ \cmidrule(r){2-3}
1190
+ & \multicolumn{2}{p{\defnwidth}}{
1191
+ Returns the arc-cosine, arc-sine, and arc-tangent of $f$, respectively.
1192
+ }
1193
+ \end{tabular}
1194
+ \newline\newline
1195
+
1196
+ \begin{tabular}{p{\methwidth} l r}
1197
+ \toprule
1198
+ \textbf{cosh} & & $f$.cosh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1199
+ \textbf{sinh} & & $f$.sinh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1200
+ \textbf{tanh} & & $f$.tanh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1201
+ \cmidrule(r){2-3}
1202
+ & \multicolumn{2}{p{\defnwidth}}{
1203
+ Returns the hyperbolic cosine, sine, and tangent of $f$, respectively.
1204
+ }
1205
+ \end{tabular}
1206
+ \newline\newline
1207
+
1208
+ \begin{tabular}{p{\methwidth} l r}
1209
+ \toprule
1210
+ \textbf{sech} & & $f$.sech(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1211
+ \textbf{csch} & & $f$.csch(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1212
+ \textbf{coth} & & $f$.coth(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1213
+ \cmidrule(r){2-3}
1214
+ & \multicolumn{2}{p{\defnwidth}}{
1215
+ Returns the hyperbolic secant, cosecant, and cotangent of $f$, respectively.
1216
+ }
1217
+ \end{tabular}
1218
+ \newline\newline
1219
+
1220
+ \begin{tabular}{p{\methwidth} l r}
1221
+ \toprule
1222
+ \textbf{acosh} & & $f$.acosh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1223
+ \textbf{asinh} & & $f$.asinh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1224
+ \textbf{atanh} & & $f$.atanh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1225
+ \cmidrule(r){2-3}
1226
+ & \multicolumn{2}{p{\defnwidth}}{
1227
+ Returns the hyperbolic arc-cosine, arc-sine, and arc-tangent of $f$, respectively.
1228
+ }
1229
+ \end{tabular}
1230
+ \newline\newline
1231
+
1232
+ \begin{tabular}{p{\methwidth} l r}
1233
+ \toprule
1234
+ \textbf{log1p} & & $f$.log1p(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1235
+ \cmidrule(r){2-3}
1236
+ & \multicolumn{2}{p{\defnwidth}}{
1237
+ Returns the logarithm of 1 plus $f$.
1238
+ }
1239
+ \end{tabular}
1240
+ \newline\newline
1241
+
1242
+ \begin{tabular}{p{\methwidth} l r}
1243
+ \toprule
1244
+ \textbf{expm1} & & $f$.expm1(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1245
+ \cmidrule(r){2-3}
1246
+ & \multicolumn{2}{p{\defnwidth}}{
1247
+ Returns the exponential of $f$ minus 1.
1248
+ }
1249
+ \end{tabular}
1250
+ \newline\newline
1251
+
1252
+ \begin{tabular}{p{\methwidth} l r}
1253
+ \toprule
1254
+ \textbf{eint} & & $f$.eint(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1255
+ \cmidrule(r){2-3}
1256
+ & \multicolumn{2}{p{\defnwidth}}{
1257
+ Returns the exponential integral of $f$. For positive $f$, the exponential integral is
1258
+ the sum of Euler's constant, of the logarithm of $f$, and of the sum for $k$ from $1$
1259
+ to infinity of $f$ to the power $k$, divided by $k$ and factorial($k$). For negative
1260
+ $f$, this method returns NaN.
1261
+ }
1262
+ \end{tabular}
1263
+ \newline\newline
1264
+
1265
+ \begin{tabular}{p{\methwidth} l r}
1266
+ \toprule
1267
+ \textbf{li2} & & $f$.li2(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1268
+ \cmidrule(r){2-3}
1269
+ & \multicolumn{2}{p{\defnwidth}}{
1270
+ Returns the real part of the dilogarithm of $f$. MPFR defines the dilogarithm as the
1271
+ integral of $-\log(1-t)/t$ from 0 to $f$.
1272
+ }
1273
+ \end{tabular}
1274
+ \newline\newline
1275
+
1276
+ \begin{tabular}{p{\methwidth} l r}
1277
+ \toprule
1278
+ \textbf{gamma} & & $f$.gamma(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1279
+ \cmidrule(r){2-3}
1280
+ & \multicolumn{2}{p{\defnwidth}}{
1281
+ Returns the value of the Gamma function on $f$. When $f$ is a negative integer, this
1282
+ method returns NaN.
1283
+ }
1284
+ \end{tabular}
1285
+ \newline\newline
1286
+
1287
+ \begin{tabular}{p{\methwidth} l r}
1288
+ \toprule
1289
+ \textbf{lngamma} & & $f$.lngamma(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1290
+ \cmidrule(r){2-3}
1291
+ & \multicolumn{2}{p{\defnwidth}}{
1292
+ Returns the value of the logarithm of the Gamma function on $f$. When
1293
+ $-2k-1 \leq f \leq -2k$, $k$ being a non-negative integer, this method returns NaN.
1294
+ }
1295
+ \end{tabular}
1296
+ \newline\newline
1297
+
1298
+ \begin{tabular}{p{\methwidth} l r}
1299
+ \toprule
1300
+ \textbf{digamma} & & $f$.digamma(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1301
+ \cmidrule(r){2-3}
1302
+ & \multicolumn{2}{p{\defnwidth}}{
1303
+ Returns the value of the Digamma (sometimes called Psi) function on $f$. When $f$ is
1304
+ negative, this method returns NaN.\newline
1305
+ \newline
1306
+ Only available in MPFR version 3.0.0 or later.
1307
+ }
1308
+ \end{tabular}
1309
+ \newline\newline
1310
+
1311
+ \begin{tabular}{p{\methwidth} l r}
1312
+ \toprule
1313
+ \textbf{zeta} & & $f$.zeta(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1314
+ \cmidrule(r){2-3}
1315
+ & \multicolumn{2}{p{\defnwidth}}{
1316
+ Returns the value of the Riemann Zeta function on $f$.
1317
+ }
1318
+ \end{tabular}
1319
+ \newline\newline
1320
+
1321
+ \begin{tabular}{p{\methwidth} l r}
1322
+ \toprule
1323
+ \textbf{erf} & & $f$.erf(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1324
+ \textbf{erfc} & & $f$.erfc(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1325
+ \cmidrule(r){2-3}
1326
+ & \multicolumn{2}{p{\defnwidth}}{
1327
+ Returns the value of the error function on $f$ (respectively the complementary error
1328
+ function on $f$).
1329
+ }
1330
+ \end{tabular}
1331
+ \newline\newline
1332
+
1333
+ \begin{tabular}{p{\methwidth} l r}
1334
+ \toprule
1335
+ \textbf{j0} & & $f$.j0(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1336
+ \textbf{j1} & & $f$.j1(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1337
+ \textbf{jn} & & $f$.jn(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1338
+ \cmidrule(r){2-3}
1339
+ & \multicolumn{2}{p{\defnwidth}}{
1340
+ Returns the value of the first kind Bessel function of order $0$ (respectively $1$ and
1341
+ $n$) on $f$. When $f$ is NaN, this method returns NaN. When $f$ is +Inf or -Inf, this
1342
+ method returns $+0$. When $f$ is zero, this method returns +Inf or -Inf, depending on
1343
+ the parity and sign of $n$, and the sign of $f$.
1344
+ }
1345
+ \end{tabular}
1346
+ \newline\newline
1347
+
1348
+ \begin{tabular}{p{\methwidth} l r}
1349
+ \toprule
1350
+ \textbf{y0} & & $f$.y0(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1351
+ \textbf{y1} & & $f$.y1(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1352
+ \textbf{yn} & & $f$.yn(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\
1353
+ \cmidrule(r){2-3}
1354
+ & \multicolumn{2}{p{\defnwidth}}{
1355
+ Returns the value of the second kind Bessel function of order $0$ (respectively $1$ and
1356
+ $n$) on $f$. When $f$ is NaN or negative, this method returns NaN. When $f$ is +Inf,
1357
+ this method returns $+0$. When $f$ is zero, this method returns +Inf or -Inf, depending
1358
+ on the parity and sign of $n$.
1359
+ }
1360
+ \end{tabular}
1361
+
1362
+
1026
1363
  \newpage
1027
1364
  \section{Random Number Functions}
1028
1365
 
@@ -1093,4 +1430,101 @@ There is also a convenience method available, \texttt{GMP::Q()}.\\
1093
1430
  }
1094
1431
  \end{tabular}
1095
1432
 
1433
+
1434
+ \newpage
1435
+ \section{Benchmarking}
1436
+
1437
+ Starting with, I believe, GMP 5.0.0, their benchmarking suite was updated to version 0.2,
1438
+ a significant improvement over version 0.1. The suite consists of 3 parts.\\\\
1439
+
1440
+ First is six individual programs that will benchmark a single concept. These are
1441
+ \texttt{multiply}, \texttt{divide}, \texttt{gcd}, \texttt{gcdext}, \texttt{rsa}, and
1442
+ \texttt{pi}.
1443
+
1444
+ Second is gexpr.c, a nifty little program (compiled with \texttt{gcc -o gexpr gexpr.c},
1445
+ or\\ \texttt{gcc -o gexpr gexpr.c -lm} on some systems). They use this basically for
1446
+ weighing the results of individual tests and stringifying them to a certain precision.
1447
+
1448
+ Third is runbench, a shell script that runs each of the six benchmark programs, each
1449
+ several times with a different set of arguments. It compiles the results, using gexpr
1450
+ to carefully calculate a final "score" for each benchmark, each benchmark family
1451
+ (\texttt{rsa} and \texttt{pi} are separated as "app" benchmarks.), and for the suite as a
1452
+ whole.
1453
+
1454
+ \subsection{gmp gem benchmarking}
1455
+
1456
+ The structure described above lends itself perfectly to some simple modifications that
1457
+ allow me to benchmark the gmp gem. Instead of using the C programs that are the
1458
+ individual benchmarks, I have converted them into Ruby programs, and called them the same
1459
+ names. When runbench executes "multiply" for example, it is running a Ruby program that
1460
+ does the same general thing as "multiply" the C program. This allows me to benchmark the
1461
+ gmp gem, and I can even compare the results with those of benchmarking GMP itself. I have
1462
+ done so below.
1463
+
1464
+ \newpage
1465
+ \subsection{Benchmark Results}
1466
+
1467
+ I've benchmarked an array of Ruby-version/GMP-version combinations, which can be compared
1468
+ with results of the actual GMPbench benchmark, in order to understand the overhead that
1469
+ Ruby and the Ruby C Extension API impose on the GMP library. The benchmarks listed were
1470
+ all executed on an Apple MacBook "5.1." booting three operating systems with rEFIt 0.14.
1471
+ Because not all of the marks from GMPbench have been ported to the Ruby gmp gem, results
1472
+ for 'base' and 'app' are not listed; they cannot be compared with GMPbench results.\\
1473
+
1474
+ \begin{LARGE}MacBook, Intel Core 2 Duo, 2 GHz, 2 GB DDR3\end{LARGE}\\
1475
+
1476
+ Mac OS X 10.6.4, x86 (32-bit)\\
1477
+ Ruby and GMP compiled with gcc 4.2.1 (Apple Inc. build 5664)\\
1478
+ \begin{tabular}{|l|l|r|r|r|r|}
1479
+ \hline
1480
+ GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\
1481
+ \hline
1482
+ 4.3.2 & multiply & 7696.5 & 7482.8 & 7608.2 & 16789 \\
1483
+ & divide & 7304.3 & 7148.0 & 7199.4 & 9872.5 \\
1484
+ & gcd & 2388.4 & 2412.1 & 2470.9 & 2938.9 \\
1485
+ & rsa & 2042.3 & 2058.0 & 2065.9 & 2136.7 \\
1486
+ \hline
1487
+ 5.0.1 & multiply & 8142.6 & 7886.0 & 7952.7 & 17925 \\
1488
+ & divide & 10256 & 10088 & 10124 & 16069 \\
1489
+ & gcd & 2498.1 & 2547.0 & 2574.2 & 3063.7 \\
1490
+ & rsa & 2132.4 & 2157.4 & 2167.9 & 2229.2 \\
1491
+ \hline
1492
+ \end{tabular}\\\\
1493
+
1494
+ Ubuntu 10.04, Kernel 2.6.32-24, x86\_64 (64-bit)\\
1495
+ Ruby and GMP compiled with gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)\\
1496
+ \begin{tabular}{|l|l|r|r|r|r|}
1497
+ \hline
1498
+ GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\
1499
+ \hline
1500
+ 4.3.2 & multiply & 7793.7 & 6825.7 & 7460.6 & 14716 \\
1501
+ & divide & 7687.6 & 7725.9 & 7473.3 & 8614.3 \\
1502
+ & gcd & 2450.1 & 2507.6 & 2476.6 & 2779.8 \\
1503
+ & rsa & 1979.1 & 2065.6 & 2059.2 & 1984.3 \\
1504
+ \hline
1505
+ 5.0.1 & multiply & 9727.1 & 7020.3 & 7902.1 & 17695 \\
1506
+ & divide & 9306.4 & 10785 & 10799 & 15629 \\
1507
+ & gcd & 2345.3 & 2525.5 & 2541.2 & 2925.1 \\
1508
+ & rsa & 2116.5 & 2117.8 & 2143.9 & 2233.4 \\
1509
+ \hline
1510
+ \end{tabular}\\\\
1511
+
1512
+ Windows 7 (64-bit)\\
1513
+ Ruby and GMP compiled with gcc 4.5.0 (tdm-1)\\
1514
+ \begin{tabular}{|l|l|r|r|r|r|}
1515
+ \hline
1516
+ GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\
1517
+ \hline
1518
+ 4.3.2 & multiply & 3514.7 & 3649.4 & 3631.9 & 6448.7 \\
1519
+ & divide & 2996.7 & 3082.0 & 3065.2 & 3717.5 \\
1520
+ & gcd & 1142.8 & 1183.3 & 1203.6 & 1359.4 \\
1521
+ & rsa & 719.41 & 730.05 & 736.03 & 757.97 \\
1522
+ \hline
1523
+ 5.0.1 & multiply & 3702.9 & 3824.1 & 3763.8 & 6835.2 \\
1524
+ & divide & 4549.7 & 4600.9 & 4609.2 & 6497.4 \\
1525
+ & gcd & 1204.9 & 1233.4 & 1235.0 & 1394.2 \\
1526
+ & rsa & 729.68 & 735.13 & 728.56 & 754.72 \\
1527
+ \hline
1528
+ \end{tabular}\\
1529
+
1096
1530
  \end{document}