gmp 0.4.7 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +31 -0
- data/README.rdoc +16 -8
- data/benchmark/multiply +1 -1
- data/benchmark/multiply.gc +57 -0
- data/benchmark/pi +126 -0
- data/benchmark/srb.sh +21 -0
- data/ext/extconf.rb +3 -0
- data/ext/gmp.c +16 -7
- data/ext/gmpbench_timing.c +1 -1
- data/ext/gmpf.c +445 -104
- data/ext/gmpq.c +25 -17
- data/ext/gmpz.c +232 -120
- data/ext/mprnd.c +23 -5
- data/ext/ruby_gmp.h +75 -9
- data/lib/gmp.rb +9 -0
- data/manual.pdf +0 -0
- data/manual.tex +494 -60
- data/test/README +1 -0
- data/test/mpfr_tcbrt.rb +95 -0
- data/test/mpfr_tisnan.rb +70 -0
- data/test/mpfr_trec_sqrt.rb +62 -0
- data/test/mpfr_tsqrt.rb +142 -6
- data/test/tc_cmp.rb +4 -4
- data/test/tc_constants.rb +10 -0
- data/test/tc_division.rb +13 -2
- data/test/tc_f_arithmetics_coersion.rb +2 -2
- data/test/tc_f_precision.rb +4 -3
- data/test/tc_fib_fac_nextprime.rb +2 -2
- data/test/tc_floor_ceil_truncate.rb +2 -2
- data/test/tc_hashes.rb +0 -2
- data/test/tc_logical_roots.rb +1 -3
- data/test/tc_mpfr_constants.rb +11 -0
- data/test/tc_mpfr_functions.rb +22 -9
- data/test/tc_mpfr_random.rb +1 -3
- data/test/tc_mpfr_rounding.rb +10 -7
- data/test/tc_q.rb +1 -3
- data/test/tc_q_basic.rb +3 -5
- data/test/tc_random.rb +1 -3
- data/test/tc_sgn_neg_abs.rb +1 -3
- data/test/tc_swap.rb +1 -3
- data/test/tc_z.rb +3 -3
- data/test/tc_z_addmul.rb +92 -0
- data/test/tc_z_basic.rb +6 -8
- data/test/tc_z_exponentiation.rb +1 -3
- data/test/tc_z_gcd_lcm_invert.rb +1 -3
- data/test/tc_z_jac_leg_rem.rb +1 -3
- data/test/tc_z_logic.rb +2 -2
- data/test/tc_z_shifts_last_bits.rb +2 -2
- data/test/tc_z_to_d_to_i.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/test/test_unit/assertions.rb +31 -0
- data/test/unit_tests.rb +33 -27
- metadata +31 -6
data/ext/mprnd.c
CHANGED
@@ -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
|
-
|
32
|
+
sprintf(name_val, "%s_RNDN", prefix);
|
27
33
|
ieee754 = rb_str_new2("roundTiesToEven");
|
28
34
|
break;
|
29
35
|
case 1:
|
30
|
-
|
36
|
+
sprintf(name_val, "%s_RNDZ", prefix);
|
31
37
|
ieee754 = rb_str_new2("roundTowardZero");
|
32
38
|
break;
|
33
39
|
case 2:
|
34
|
-
|
40
|
+
sprintf(name_val, "%s_RNDU", prefix);
|
35
41
|
ieee754 = rb_str_new2("roundTowardPositive");
|
36
42
|
break;
|
37
43
|
case 3:
|
38
|
-
|
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
|
-
|
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 */
|
data/ext/ruby_gmp.h
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
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 */
|
data/lib/gmp.rb
ADDED
@@ -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\
|
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.
|
32
|
-
\multicolumn{2}{r}{\large{
|
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
|
-
\
|
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
|
-
\
|
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 '\
|
92
|
-
near you, see \
|
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
|
-
|
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
|
108
|
-
endorsed or supported by GNU or the GMP team. The gmp gem also
|
109
|
-
with GMP, so GMP must be compiled
|
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
|
128
|
-
can use the gmp gem there too. Please report problems
|
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. "
|
131
|
-
check"
|
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
|
140
|
-
completeness.\\
|
170
|
+
That's all. I don't intend to test any older versions.\\
|
141
171
|
|
142
|
-
|
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
|
-
|
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 \
|
237
|
-
|
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
|
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 \
|
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 \
|
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
|
-
\
|
353
|
-
|
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
|
-
\
|
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
|
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
|
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
|
-
|
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
|
461
|
-
|
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
|
473
|
-
|
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
|
485
|
-
|
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 \
|
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}
|