gmp 0.5.41 → 0.5.47
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +21 -0
- data/FEATURES.html +37 -38
- data/README.html +511 -0
- data/README.markdown +494 -0
- data/benchmark/divide +0 -0
- data/benchmark/gcd +0 -0
- data/benchmark/multiply +0 -0
- data/benchmark/multiply.fnl +0 -0
- data/benchmark/multiply.gc +0 -0
- data/benchmark/pi +0 -0
- data/benchmark/rsa +0 -0
- data/benchmark/runbench +0 -0
- data/benchmark/srb.sh +0 -0
- data/ext/gmp.c +0 -42
- data/ext/gmpf.c +64 -33
- data/ext/gmpq.c +88 -1
- data/ext/gmpz.c +151 -19
- data/ext/ruby_gmp.h +16 -10
- data/manual.pdf +0 -0
- data/manual.tex +50 -14
- data/test/gmp_tgcd.rb +18 -18
- data/test/mpfr_tcbrt.rb +1 -1
- data/test/mpfr_tconst_euler.rb +10 -7
- data/test/mpfr_tisnan.rb +1 -1
- data/test/mpfr_trec_sqrt.rb +1 -1
- data/test/mpfr_tsqrt.rb +1 -1
- data/test/tc_cmp.rb +7 -2
- data/test/tc_constants.rb +1 -1
- data/test/tc_division.rb +1 -1
- data/test/tc_f_arithmetics_coersion.rb +1 -1
- data/test/tc_f_precision.rb +1 -1
- data/test/tc_fib_fac_nextprime.rb +1 -1
- data/test/tc_floor_ceil_truncate.rb +1 -1
- data/test/tc_hashes.rb +26 -1
- data/test/tc_logical_roots.rb +1 -1
- data/test/tc_mpfr_constants.rb +1 -1
- data/test/tc_mpfr_functions.rb +1 -1
- data/test/tc_mpfr_random.rb +1 -1
- data/test/tc_mpfr_rounding.rb +3 -3
- data/test/tc_q.rb +1 -1
- data/test/tc_q_basic.rb +1 -1
- data/test/tc_random.rb +1 -1
- data/test/tc_sgn_neg_abs.rb +1 -1
- data/test/tc_swap.rb +1 -1
- data/test/tc_z.rb +34 -1
- data/test/tc_z_addmul.rb +1 -1
- data/test/tc_z_basic.rb +1 -1
- data/test/tc_z_exponentiation.rb +1 -1
- data/test/tc_z_functional_mappings.rb +42 -6
- data/test/tc_z_gcd_lcm_invert.rb +1 -1
- data/test/tc_z_jac_leg_rem.rb +1 -1
- data/test/tc_z_logic.rb +1 -1
- data/test/tc_z_shifts_last_bits.rb +1 -1
- data/test/tc_z_submul.rb +1 -1
- data/test/tc_z_to_dis.rb +1 -1
- data/test/tc_zerodivisionexceptions.rb +1 -1
- data/test/test_helper.rb +2 -1
- data/test/unit_tests.rb +1 -1
- metadata +70 -89
- data/README.rdoc +0 -450
data/CHANGELOG
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
0.6.7:
|
2
|
+
* Added 9th set of Functional Mappings: GMP::Z.divisible?
|
3
|
+
* Added 11th set of Functional Mappings: GMP::Z.congruent?
|
4
|
+
|
5
|
+
0.5.47:
|
6
|
+
* Probably last release before 0.6.7
|
7
|
+
* Added GMP::Q#hash and GMP::Q#eql?; tested.
|
8
|
+
* Added optional parameter to GMP::Z.new(String), the base; tested.
|
9
|
+
* Added GMP::F.mpfr_buildopt_tls_p() when MPFR > 2.x.x.
|
10
|
+
* Added GMP::F.mpfr_buildopt_decimal_p() when MPFR > 2.x.x.
|
11
|
+
* I'm seeing weird failures on tests with JRuby 1.6.5... they are flickering though.
|
12
|
+
GMP::Z(GMP::GMP_NUMB_MAX) is not happy... need to research.
|
13
|
+
* If using MPFR 3.1.0, the random number generator tests will fail, I imagine because
|
14
|
+
of this new functionality, documented on the MPFR site:
|
15
|
+
"The mpfr_urandom and mpfr_urandomb functions now return identical values on
|
16
|
+
processors with different word size (assuming the same random seed, and since the
|
17
|
+
GMP random generator does not depend itself on the word size, cf
|
18
|
+
http://gmplib.org/list-archives/gmp-devel/2010-September/001642.html)."
|
19
|
+
* Unit test results: 118 tests, 16396 assertions, 0 failures, 0 errors
|
20
|
+
* Unit test results: 99 tests, 5118 assertions, 0 failures, 0 errors (w/o MPFR)
|
21
|
+
|
1
22
|
0.5.41:
|
2
23
|
* Added first five sets of Functional Mappings. These will be the primary new features
|
3
24
|
of 0.6.
|
data/FEATURES.html
CHANGED
@@ -57,7 +57,7 @@ Ext.onReady(function(){
|
|
57
57
|
['GMP::Z#-<br />GMP::Z#sub!', "mpz_sub<br />mpz_sub_ui<br />mpz_add_ui", "yes","yes","yes", "no"],
|
58
58
|
['GMP::Z#*', "mpz_mul<br />mpz_mul_si", "yes","yes","yes", "no"],
|
59
59
|
['GMP::Z#addmul!', "mpz_addmul<br />mpz_addmul_ui", "yes","yes","yes", "no"],
|
60
|
-
['GMP::Z#submul!', "mpz_submul<br />mpz_submul_ui",
|
60
|
+
['GMP::Z#submul!', "mpz_submul<br />mpz_submul_ui", "yes","yes","yes", "no"],
|
61
61
|
['GMP::Z#<<', "mpz_mul_2exp", "yes","yes", "", "no"],
|
62
62
|
['GMP::Z#-@<br />' +
|
63
63
|
'GMP::Z#neg<br />GMP::Z#neg!', "mpz_neg", "yes","yes", "", "no"],
|
@@ -79,7 +79,7 @@ Ext.onReady(function(){
|
|
79
79
|
['', "mpz_cdiv_q_2exp", "no", "no", "no", "no"],
|
80
80
|
['', "mpz_cdiv_r_2exp", "no", "no", "no", "no"],
|
81
81
|
['GMP::Z#%', "mpz_mod<br />mpz_mod_ui", "yes","yes", "", "no"],
|
82
|
-
['GMP::Z#divisible?', "mpz_divisible_p<br />mpz_divisible_ui_p",
|
82
|
+
['GMP::Z#divisible?', "mpz_divisible_p<br />mpz_divisible_ui_p", "yes","yes","yes", "no"],
|
83
83
|
['', "mpz_divisible_2exp_p", "no", "no", "no", "no"],
|
84
84
|
['', "mpz_congruent_p<br />mpz_congruent_ui_p", "no", "no", "no", "no"],
|
85
85
|
['', "mpz_congruent_2exp_p", "no", "no", "no", "no"],
|
@@ -95,7 +95,7 @@ Ext.onReady(function(){
|
|
95
95
|
['GMP::Z#next_prime<br />' +
|
96
96
|
'GMP::Z#next_prime!', "mpz_nextprime", "yes","yes", "", "no"],
|
97
97
|
['GMP::Z#gcd', "mpz_gcd<br />mpz_gcd_ui", "yes","yes", "", "no"],
|
98
|
-
['GMP::Z#gcdext', "mpz_gcdext",
|
98
|
+
['GMP::Z#gcdext', "mpz_gcdext", "yes","yes", "", "no"],
|
99
99
|
['', "mpz_lcm<br />mpz_lcm_ui", "no", "no", "no", "no"],
|
100
100
|
['GMP::Z#invert', "mpz_invert", "yes","yes", "", "no"],
|
101
101
|
['GMP::Z#jacobi<br />GMP::Z.jacobi',"mpz_jacobi", "yes","yes", "", "no"],
|
@@ -115,8 +115,8 @@ Ext.onReady(function(){
|
|
115
115
|
'GMP::Z#><br />GMP::Z#>=', "mpz_cmp<br />mpz_cmp_si<br />mpz_cmp_ui", "yes","yes", "", "no"],
|
116
116
|
['GMP::Z#cmpabs', "mpz_cmpabs", "yes","yes", "", "no"],
|
117
117
|
['GMP::Z#sgn', "mpz_sgn", "yes","yes", "", "no"],
|
118
|
-
['GMP::Z#eql?', "mpz_get_str",
|
119
|
-
['GMP::Z#hash', "mpz_get_str",
|
118
|
+
['GMP::Z#eql?', "mpz_get_str", "yes","yes", "","n/a"],
|
119
|
+
['GMP::Z#hash', "mpz_get_str", "yes","yes", "","n/a"],
|
120
120
|
['GMP::Z#&', "mpz_and", "yes","yes", "", "no"],
|
121
121
|
['GMP::Z#|', "mpz_ior", "yes","yes", "", "no"],
|
122
122
|
['GMP::Z#^', "mpz_xor", "yes","yes", "", "no"],
|
@@ -154,41 +154,40 @@ Ext.onReady(function(){
|
|
154
154
|
['GMP::Z.mul', "mpz_mul<br />mpz_mul_si<br />mpz_mul_ui", "no", "no", "no", "no"],
|
155
155
|
['GMP::Z.addmul', "mpz_addmul<br />mpz_addmul_ui", "no", "no", "no", "no"],
|
156
156
|
['GMP::Z.submul', "mpz_submul<br />mpz_submul_ui", "no", "no", "no", "no"],
|
157
|
-
['',
|
158
|
-
['',
|
159
|
-
['',
|
157
|
+
['GMP::Z.mul_2exp', "mpz_mul_2exp", "no", "no", "no", "no"],
|
158
|
+
['GMP::Z.neg', "mpz_neg", "no", "no", "no", "no"],
|
159
|
+
['GMP::Z.abs', "mpz_abs", "no", "no", "no", "no"],
|
160
160
|
['GMP::Z.divexact', "mpz_divexact<br />mpz_divexact_ui", "no", "no", "no", "no"],
|
161
161
|
['', "mpz_tdiv_q", "no", "no", "no", "no"],
|
162
162
|
['', "mpz_tdiv_r", "no", "no", "no", "no"],
|
163
163
|
['', "mpz_tdiv_qr", "no", "no", "no", "no"],
|
164
|
-
|
165
|
-
['GMP::Z
|
166
|
-
['
|
167
|
-
['
|
168
|
-
['
|
169
|
-
['GMP::Z
|
170
|
-
['GMP::Z
|
171
|
-
['GMP::Z#cdiv', "mpz_cdiv_q", "yes","yes","yes", "no"],
|
164
|
+
['GMP::Z.tdiv_q_2exp', "mpz_tdiv_q_2exp", "no", "no", "no", "no"],
|
165
|
+
['GMP::Z.tdiv_r_2exp', "mpz_tdiv_r_2exp", "no", "no", "no", "no"],
|
166
|
+
['', "mpz_fdiv_q", "no", "no", "no", "no"],
|
167
|
+
['', "mpz_fdiv_r", "no", "no", "no", "no"],
|
168
|
+
['', "mpz_fdiv_rq", "no", "no", "no", "no"],
|
169
|
+
['GMP::Z.fdiv_q_2exp', "mpz_fdiv_q_2exp", "no", "no", "no", "no"],
|
170
|
+
['GMP::Z.fdiv_r_2exp', "mpz_fdiv_r_2exp", "no", "no", "no", "no"],
|
171
|
+
/*['GMP::Z#cdiv', "mpz_cdiv_q", "yes","yes","yes", "no"],
|
172
172
|
['GMP::Z#cmod', "mpz_cdiv_r", "yes","yes","yes", "no"],
|
173
|
-
['GMP::Z#cdivmod', "mpz_cdiv_qr", "no", "no", "no", "no"]
|
174
|
-
['',
|
175
|
-
['',
|
176
|
-
['GMP::Z#%', "mpz_mod<br />mpz_mod_ui", "yes","yes", "", "no"]
|
177
|
-
['GMP::Z
|
178
|
-
['', "mpz_divisible_2exp_p", "no", "no", "no", "no"]
|
179
|
-
['',
|
180
|
-
['', "mpz_congruent_2exp_p", "no", "no", "no", "no"],
|
173
|
+
['GMP::Z#cdivmod', "mpz_cdiv_qr", "no", "no", "no", "no"],*/
|
174
|
+
['GMP::Z.cdiv_q_2exp', "mpz_cdiv_q_2exp", "no", "no", "no", "no"],
|
175
|
+
['GMP::Z.fdiv_r_2exp', "mpz_cdiv_r_2exp", "no", "no", "no", "no"],
|
176
|
+
/*['GMP::Z#%', "mpz_mod<br />mpz_mod_ui", "yes","yes", "", "no"],*/
|
177
|
+
['GMP::Z.divisible?', "mpz_divisible_p<br />mpz_divisible_ui_p", "no", "no", "no", "no"],
|
178
|
+
/*['', "mpz_divisible_2exp_p", "no", "no", "no", "no"],*/
|
179
|
+
['GMP::Z.congruent?', "mpz_congruent_p<br />mpz_congruent_ui_p", "no", "no", "no", "no"],
|
180
|
+
/*['', "mpz_congruent_2exp_p", "no", "no", "no", "no"],
|
181
181
|
['GMP::Z#**<br />GMP::Z.pow', "mpz_pow_ui", "yes","yes", "", "no"],
|
182
182
|
['GMP::Z#powmod', "mpz_powm<br />mpz_powm_ui", "yes","yes", "", "no"],
|
183
183
|
['GMP::Z#root', "mpz_root", "yes","yes", "", "no"],
|
184
|
-
['', "mpz_rootrem", "no", "no", "no", "no"]
|
185
|
-
['GMP::Z
|
186
|
-
['
|
187
|
-
['
|
188
|
-
['
|
189
|
-
['
|
190
|
-
['GMP::Z
|
191
|
-
'GMP::Z#next_prime!', "mpz_nextprime", "yes","yes", "", "no"],*/
|
184
|
+
['', "mpz_rootrem", "no", "no", "no", "no"],*/
|
185
|
+
['GMP::Z.sqrt', "mpz_sqrt", "no", "no", "no", "no"],
|
186
|
+
['', "mpz_sqrtrem", "no", "no", "no", "no"],
|
187
|
+
['', "mpz_perfect_power_p", "no", "no", "no", "no"],
|
188
|
+
['', "mpz_perfect_square_p", "no", "no", "no", "no"],
|
189
|
+
['', "mpz_probab_prime_p", "no", "no", "no", "no"],
|
190
|
+
['GMP::Z.nextprime', "mpz_nextprime", "no", "no", "no", "no"],
|
192
191
|
['', "mpz_gcd<br />mpz_gcd_ui", "no", "no", "no", "no"],
|
193
192
|
['', "mpz_gcdext", "no", "no", "no", "no"],
|
194
193
|
['GMP::Z.lcm', "mpz_lcm<br />mpz_lcm_ui", "no", "no", "no", "no"],
|
@@ -214,22 +213,22 @@ Ext.onReady(function(){
|
|
214
213
|
['GMP::Z#hash', "mpz_get_str", "no","yes", "","n/a"],
|
215
214
|
['GMP::Z#&', "mpz_and", "yes","yes", "", "no"],
|
216
215
|
['GMP::Z#|', "mpz_ior", "yes","yes", "", "no"],
|
217
|
-
['GMP::Z#^', "mpz_xor", "yes","yes", "", "no"]
|
218
|
-
['GMP::Z
|
219
|
-
['GMP::Z#popcount', "mpz_popcount", "yes","yes", "", "no"],
|
216
|
+
['GMP::Z#^', "mpz_xor", "yes","yes", "", "no"],*/
|
217
|
+
['GMP::Z.com', "mpz_com", "no", "no", "no", "no"],
|
218
|
+
/*['GMP::Z#popcount', "mpz_popcount", "yes","yes", "", "no"],
|
220
219
|
['', "mpz_hamdist", "no", "no", "no", "no"],
|
221
220
|
['GMP::Z#scan0', "mpz_scan0", "yes","yes", "", "no"],
|
222
221
|
['GMP::Z#scan1', "mpz_scan1", "yes","yes", "", "no"],
|
223
222
|
['GMP::Z#[]=', "mpz_setbit<br />mpz_clrbit", "yes","yes", "", "no"],
|
224
223
|
['', "mpz_combit", "no", "no", "no", "no"],
|
225
|
-
['GMP::Z#[]', "mpz_tstbit", "yes","yes", "", "no"]
|
224
|
+
['GMP::Z#[]', "mpz_tstbit", "yes","yes", "", "no"],*/
|
226
225
|
['', "mpz_fits_ulong_p", "no", "no", "no", "no"],
|
227
226
|
['', "mpz_fits_slong_p", "no", "no", "no", "no"],
|
228
227
|
['', "mpz_fits_uint_p", "no", "no", "no", "no"],
|
229
228
|
['', "mpz_fits_sint_p", "no", "no", "no", "no"],
|
230
229
|
['', "mpz_fits_ushort_p", "no", "no", "no", "no"],
|
231
230
|
['', "mpz_fits_sshort_p", "no", "no", "no", "no"],
|
232
|
-
['GMP::Z#even?', "mpz_even_p", "yes","yes", "", "no"],
|
231
|
+
/*['GMP::Z#even?', "mpz_even_p", "yes","yes", "", "no"],
|
233
232
|
['GMP::Z#odd?', "mpz_odd_p", "yes","yes", "", "no"],
|
234
233
|
['GMP::Z#sizeinbase<br />' +
|
235
234
|
'GMP::Z#size_in_base', "mpz_sizeinbase", "yes","yes", "", "no"],
|
@@ -533,4 +532,4 @@ Ext.onReady(function(){
|
|
533
532
|
<div id='mpq-grid'></div>
|
534
533
|
<div id='mpf-grid'></div>
|
535
534
|
</body>
|
536
|
-
</html>
|
535
|
+
</html>
|
data/README.html
ADDED
@@ -0,0 +1,511 @@
|
|
1
|
+
<h1>gmp</h1>
|
2
|
+
|
3
|
+
<p>gmp is library providing Ruby bindings to GMP library. Here is the introduction
|
4
|
+
paragraph at <a href="http://gmplib.org/#WHAT">their homepage</a>:</p>
|
5
|
+
|
6
|
+
<blockquote><p>GMP is a free library for arbitrary precision arithmetic, operating on
|
7
|
+
signed integers, rational numbers, and floating point numbers. There is no
|
8
|
+
practical limit to the precision except the ones implied by the available
|
9
|
+
memory in the machine GMP runs on. GMP has a rich set of functions, and the
|
10
|
+
functions have a regular interface.</p>
|
11
|
+
|
12
|
+
<p>The main target applications for GMP are cryptography applications and
|
13
|
+
research, Internet security applications, algebra systems, computational
|
14
|
+
algebra research, etc.</p>
|
15
|
+
|
16
|
+
<p>GMP is carefully designed to be as fast as possible, both for small operands
|
17
|
+
and for huge operands. The speed is achieved by using fullwords as the basic
|
18
|
+
arithmetic type, by using fast algorithms, with highly optimised assembly
|
19
|
+
code for the most common inner loops for a lot of CPUs, and by a general
|
20
|
+
emphasis on speed.</p>
|
21
|
+
|
22
|
+
<p>GMP is faster than any other bignum library. The advantage for GMP increases
|
23
|
+
with the operand sizes for many operations, since GMP uses asymptotically
|
24
|
+
faster algorithms.</p>
|
25
|
+
|
26
|
+
<p>The first GMP release was made in 1991. It is continually developed and
|
27
|
+
maintained, with a new release about once a year.</p>
|
28
|
+
|
29
|
+
<p>GMP is distributed under the GNU LGPL. This license makes the library free to
|
30
|
+
use, share, and improve, and allows you to pass on the result. The license
|
31
|
+
gives freedoms, but also sets firm restrictions on the use with non-free
|
32
|
+
programs.</p>
|
33
|
+
|
34
|
+
<p>GMP is part of the GNU project. For more information about the GNU project,
|
35
|
+
please see the official GNU web site.</p>
|
36
|
+
|
37
|
+
<p>GMP's main target platforms are Unix-type systems, such as GNU/Linux,
|
38
|
+
Solaris, HP-UX, Mac OS X/Darwin, BSD, AIX, etc. It also is known to work on
|
39
|
+
Windoze in 32-bit mode.</p>
|
40
|
+
|
41
|
+
<p>GMP is brought to you by a team listed in the manual.</p>
|
42
|
+
|
43
|
+
<p>GMP is carefully developed and maintained, both technically and legally. We
|
44
|
+
of course inspect and test contributed code carefully, but equally
|
45
|
+
importantly we make sure we have the legal right to distribute the
|
46
|
+
contributions, meaning users can safely use GMP. To achieve this, we will ask
|
47
|
+
contributors to sign paperwork where they allow us to distribute their work."</p></blockquote>
|
48
|
+
|
49
|
+
<p>Only GMP 4 or newer is supported. The following environments have been tested
|
50
|
+
by me: gmp gem 0.5.41 on:</p>
|
51
|
+
|
52
|
+
<table border="1">
|
53
|
+
<tr>
|
54
|
+
<th>Platform</th>
|
55
|
+
<th>Ruby</th>
|
56
|
+
<th>GMP (MPFR)</th>
|
57
|
+
</tr>
|
58
|
+
<tr>
|
59
|
+
<td rowspan="3">Linux (Ubuntu NR 10.04) on x86 (32-bit)</td>
|
60
|
+
<td>(MRI) Ruby 1.8.7</td>
|
61
|
+
<td>GMP 4.3.1 (2.4.2)<br />
|
62
|
+
GMP 4.3.2 (2.4.2)<br />
|
63
|
+
GMP 5.0.1 (3.0.0)</td>
|
64
|
+
</tr>
|
65
|
+
<tr>
|
66
|
+
<td>(MRI) Ruby 1.9.1</td>
|
67
|
+
<td>GMP 4.3.1 (2.4.2)<br />
|
68
|
+
GMP 4.3.2 (2.4.2)<br />
|
69
|
+
GMP 5.0.1 (3.0.0)</td>
|
70
|
+
</tr>
|
71
|
+
<tr>
|
72
|
+
<td>(MRI) Ruby 1.9.2</td>
|
73
|
+
<td>GMP 4.3.1 (2.4.2)<br />
|
74
|
+
GMP 4.3.2 (2.4.2)<br />
|
75
|
+
GMP 5.0.1 (3.0.0)</td>
|
76
|
+
</tr>
|
77
|
+
<tr>
|
78
|
+
<td rowspan="4">Linux (Ubuntu 10.04) on x86_64 (64-bit)</td>
|
79
|
+
<td>(MRI) Ruby 1.8.7</td>
|
80
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
81
|
+
GMP 5.0.1 (3.0.0)</td>
|
82
|
+
</tr>
|
83
|
+
<tr>
|
84
|
+
<td>(MRI) Ruby 1.9.1</td>
|
85
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
86
|
+
GMP 5.0.1 (3.0.0)</td>
|
87
|
+
</tr>
|
88
|
+
<tr>
|
89
|
+
<td>(MRI) Ruby 1.9.2</td>
|
90
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
91
|
+
GMP 5.0.1 (3.0.0)</td>
|
92
|
+
</tr>
|
93
|
+
<tr>
|
94
|
+
<td>(RBX) Rubinius 1.1.0</td>
|
95
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
96
|
+
GMP 5.0.1 (3.0.0)</td>
|
97
|
+
</tr>
|
98
|
+
<tr>
|
99
|
+
<td rowspan="4">Mac OS X 10.6.4 on x86_64 (64-bit)</td>
|
100
|
+
<td>(MRI) Ruby 1.8.7</td>
|
101
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
102
|
+
GMP 5.0.1 (3.0.0)</td>
|
103
|
+
</tr>
|
104
|
+
<tr>
|
105
|
+
<td>(MRI) Ruby 1.9.1</td>
|
106
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
107
|
+
GMP 5.0.1 (3.0.0)</td>
|
108
|
+
</tr>
|
109
|
+
<tr>
|
110
|
+
<td>(MRI) Ruby 1.9.2</td>
|
111
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
112
|
+
GMP 5.0.1 (3.0.0)</td>
|
113
|
+
</tr>
|
114
|
+
<tr>
|
115
|
+
<td>(RBX) Rubinius 1.1.0</td>
|
116
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
117
|
+
GMP 5.0.1 (3.0.0)</td>
|
118
|
+
</tr>
|
119
|
+
<tr>
|
120
|
+
<td rowspan="3">Windows 7 on x86_64 (64-bit)</td>
|
121
|
+
<td>(MRI) Ruby 1.8.7</td>
|
122
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
123
|
+
GMP 5.0.1 (3.0.0)</td>
|
124
|
+
</tr>
|
125
|
+
<tr>
|
126
|
+
<td>(MRI) Ruby 1.9.1</td>
|
127
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
128
|
+
GMP 5.0.1 (3.0.0)</td>
|
129
|
+
</tr>
|
130
|
+
<tr>
|
131
|
+
<td>(MRI) Ruby 1.9.2</td>
|
132
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
133
|
+
GMP 5.0.1 (3.0.0)</td>
|
134
|
+
</tr>
|
135
|
+
<tr>
|
136
|
+
<td>Windows XP on x86 (32-bit)</td>
|
137
|
+
<td>(MRI) Ruby 1.9.1</td>
|
138
|
+
<td>GMP 4.3.2 (2.4.2)<br />
|
139
|
+
GMP 5.0.1 (3.0.0)</td>
|
140
|
+
</tr>
|
141
|
+
</table>
|
142
|
+
|
143
|
+
|
144
|
+
<h2>Authors</h2>
|
145
|
+
|
146
|
+
<ul>
|
147
|
+
<li>Tomasz Wegrzanowski</li>
|
148
|
+
<li>srawlins</li>
|
149
|
+
</ul>
|
150
|
+
|
151
|
+
|
152
|
+
<h2>Constants</h2>
|
153
|
+
|
154
|
+
<p>The GMP module includes the following constants. Mathematical constants, such
|
155
|
+
as pi, are defined under class methods of GMP::F, listed below.</p>
|
156
|
+
|
157
|
+
<ul>
|
158
|
+
<li><code>GMP::GMP_VERSION</code> - A string like "5.0.1"</li>
|
159
|
+
<li><code>GMP::GMP_CC</code> - The compiler used to compile GMP</li>
|
160
|
+
<li><code>GMP::GMP_CFLAGS</code> - The CFLAGS used to compile GMP</li>
|
161
|
+
<li><code>GMP::GMP\_BITS_PER_LIMB</code> The number of bits per limb</li>
|
162
|
+
<li><code>GMP::GMP_NUMB_MAX</code> - The maximum value that can be stored in the number part of a limb</li>
|
163
|
+
</ul>
|
164
|
+
|
165
|
+
|
166
|
+
<p>if MPFR is available:
|
167
|
+
* <code>GMP::MPFR_VERSION</code> - A string like "2.4.2"
|
168
|
+
* <code>GMP::MPFR\_PREC_MIN</code> - The minimum precision available
|
169
|
+
* <code>GMP::MPFR_PREC_MAX</code> - The maximum precision available
|
170
|
+
* <code>GMP::GMP_RNDN</code> - The constant representing "round to nearest"
|
171
|
+
* <code>GMP::GMP_RNDZ</code> - The constant representing "round toward zero"
|
172
|
+
* <code>GMP::GMP_RNDU</code> - The constant representing "round toward plus infinity"
|
173
|
+
* <code>GMP::GMP_RNDD</code> - The constant representing "round toward minus infinity"</p>
|
174
|
+
|
175
|
+
<p>New in MPFR 3.0.0:
|
176
|
+
* <code>GMP::MPFR_RNDN</code>
|
177
|
+
* <code>GMP::MPFR_RNDZ</code>
|
178
|
+
* <code>GMP::MPFR_RNDU</code>
|
179
|
+
* <code>GMP::MPFR_RNDD</code>
|
180
|
+
* <code>GMP::MPFR_RNDA</code> - The constant representing "round away from zero"</p>
|
181
|
+
|
182
|
+
<h2>Classes</h2>
|
183
|
+
|
184
|
+
<p>The GMP module is provided with following classes:
|
185
|
+
* <code>GMP::Z</code> - infinite precision integer numbers
|
186
|
+
* <code>GMP::Q</code> - infinite precision rational numbers
|
187
|
+
* <code>GMP::F</code> - arbitrary precision floating point numbers
|
188
|
+
* <code>GMP::RandState</code> - states of individual random number generators</p>
|
189
|
+
|
190
|
+
<p>Numbers are created by using <code>new()</code>. Constructors can take following arguments:</p>
|
191
|
+
|
192
|
+
<pre><code>GMP::Z.new()
|
193
|
+
GMP::Z.new(GMP::Z)
|
194
|
+
GMP::Z.new(Fixnum)
|
195
|
+
GMP::Z.new(Bignum)
|
196
|
+
GMP::Z.new(String)
|
197
|
+
GMP::Q.new()
|
198
|
+
GMP::Q.new(GMP::Q)
|
199
|
+
GMP::Q.new(String)
|
200
|
+
GMP::Q.new(any GMP::Z initializer)
|
201
|
+
GMP::Q.new(any GMP::Z initializer, any GMP::Z initializer)
|
202
|
+
GMP::F.new()
|
203
|
+
GMP::F.new(GMP::Z, precision=0)
|
204
|
+
GMP::F.new(GMP::Q, precision=0)
|
205
|
+
GMP::F.new(GMP::F)
|
206
|
+
GMP::F.new(GMP::F, precision)
|
207
|
+
GMP::F.new(String, precision=0)
|
208
|
+
GMP::F.new(Fixnum, precision=0)
|
209
|
+
GMP::F.new(Bignum, precision=0)
|
210
|
+
GMP::F.new(Float, precision=0)
|
211
|
+
GMP::RandState.new(\[algorithm\] \[, algorithm_args\])
|
212
|
+
</code></pre>
|
213
|
+
|
214
|
+
<p>You can also call them as:</p>
|
215
|
+
|
216
|
+
<pre><code>GMP.Z(args)
|
217
|
+
GMP.Q(args)
|
218
|
+
GMP.F(args)
|
219
|
+
GMP.RandState()
|
220
|
+
</code></pre>
|
221
|
+
|
222
|
+
<h2>Methods</h2>
|
223
|
+
|
224
|
+
<pre><code>GMP::Z, GMP::Q and GMP::F
|
225
|
+
+ addition
|
226
|
+
- substraction
|
227
|
+
* multiplication
|
228
|
+
/ division
|
229
|
+
to_s convert to string. For GMP::Z, this method takes
|
230
|
+
one optional argument, a base. The base can be a
|
231
|
+
Fixnum in the ranges \[2, 62\] or \[-36, -2\] or a
|
232
|
+
Symbol: :bin, :oct, :dec, or :hex.
|
233
|
+
-@ negation
|
234
|
+
neg! in-place negation
|
235
|
+
abs absolute value
|
236
|
+
asb! in-place absolute value
|
237
|
+
coerce promotion of arguments
|
238
|
+
== equality test
|
239
|
+
<=>,>=,>,<=,< comparisions
|
240
|
+
class methods of GMP::Z
|
241
|
+
fac(n) factorial of n
|
242
|
+
fib(n) nth fibonacci number
|
243
|
+
pow(n,m) n to mth power
|
244
|
+
GMP::Z and GMP::Q
|
245
|
+
swap efficiently swap contents of two objects, there
|
246
|
+
is no GMP::F.swap because various GMP::F objects
|
247
|
+
may have different precisions, which would make
|
248
|
+
them unswapable
|
249
|
+
GMP::Z
|
250
|
+
to_i convert to Fixnum or Bignum
|
251
|
+
add! in-place addition
|
252
|
+
sub! in-place subtraction
|
253
|
+
addmul!(b,c) in-place += b*c
|
254
|
+
submul!(b,c) in-place -= b*c
|
255
|
+
tdiv,fdiv,cdiv truncate, floor and ceil division
|
256
|
+
tmod,fmod,cmod truncate, floor and ceil modulus
|
257
|
+
>> shift right, floor
|
258
|
+
divisible?(b) true if divisible by b
|
259
|
+
** power
|
260
|
+
powmod power modulo
|
261
|
+
\[\],\[\]= testing and setting bits (as booleans)
|
262
|
+
scan0,scan1 starting at bitnr (1st arg), scan for a 0 or 1
|
263
|
+
(respectively), then return the index of the
|
264
|
+
first instance.
|
265
|
+
cmpabs comparison of absolute value
|
266
|
+
com 2's complement
|
267
|
+
com! in-place 2's complement
|
268
|
+
&,|,^ logical operations: and, or, xor
|
269
|
+
even? is even
|
270
|
+
odd? is odd
|
271
|
+
<< shift left
|
272
|
+
tshr shift right, truncate
|
273
|
+
lastbits_pos(n) last n bits of object, modulo if negative
|
274
|
+
lastbits_sgn(n) last n bits of object, preserve sign
|
275
|
+
power? is perfect power
|
276
|
+
square? is perfect square
|
277
|
+
sqrt square root
|
278
|
+
sqrt! change the object into its square root
|
279
|
+
sqrtrem square root, remainder
|
280
|
+
root(n) nth root
|
281
|
+
probab_prime? 0 if composite, 1 if probably prime, 2 if
|
282
|
+
certainly prime
|
283
|
+
nextprime next *probable* prime
|
284
|
+
nextprime! change the object into its next *probable* prime
|
285
|
+
gcd, gcdext greatest common divisor
|
286
|
+
invert(m) invert mod m
|
287
|
+
jacobi jacobi symbol
|
288
|
+
legendre legendre symbol
|
289
|
+
remove(n) remove all occurences of factor n
|
290
|
+
popcount the number of bits equal to 1
|
291
|
+
sizeinbase(b) digits in base b
|
292
|
+
size_in_bin digits in binary
|
293
|
+
size number of limbs
|
294
|
+
GMP::Q
|
295
|
+
num numerator
|
296
|
+
den denominator
|
297
|
+
inv inversion
|
298
|
+
inv! in-place inversion
|
299
|
+
floor,ceil,trunc nearest integer
|
300
|
+
class methods of GMP::F
|
301
|
+
default_prec get default precision
|
302
|
+
default_prec= set default precision
|
303
|
+
GMP::F
|
304
|
+
prec get precision
|
305
|
+
floor,ceil,trunc nearest integer, GMP::F is returned, not GMP::Z
|
306
|
+
floor!,ceil!,trunc! in-place nearest integer
|
307
|
+
GMP::RandState
|
308
|
+
seed(integer) seed the generator with a Fixnum or GMP::Z
|
309
|
+
urandomb(fixnum) get uniformly distributed random number between 0
|
310
|
+
and 2^fixnum-1, inclusive
|
311
|
+
urandomm(integer) get uniformly distributed random number between 0
|
312
|
+
and integer-1, inclusive
|
313
|
+
GMP (timing functions for GMPbench (0.2))
|
314
|
+
cputime milliseconds of cpu time since Ruby start
|
315
|
+
time times the execution of a block
|
316
|
+
|
317
|
+
*only if MPFR is available*
|
318
|
+
class methods of GMP::F
|
319
|
+
const_log2 returns the natural log of 2
|
320
|
+
const_pi returns pi
|
321
|
+
const_euler returns euler
|
322
|
+
const_catalan returns catalan
|
323
|
+
mpfr_buildopt_tls_p returns whether MPFR was built as thread safe
|
324
|
+
mpfr_buildopt_decimal_p returns whether MPFR was compiled with decimal
|
325
|
+
float support
|
326
|
+
GMP::F
|
327
|
+
sqrt square root of the object
|
328
|
+
rec_sqrt square root of the recprical of the object
|
329
|
+
cbrt cube root of the object
|
330
|
+
** power
|
331
|
+
log natural logarithm of object
|
332
|
+
log2 binary logarithm of object
|
333
|
+
log10 decimal logarithm of object
|
334
|
+
exp e^object
|
335
|
+
exp2 2^object
|
336
|
+
exp10 10^object
|
337
|
+
log1p the same as (object + 1).log, with better
|
338
|
+
precision
|
339
|
+
expm1 the same as (object.exp) - 1, with better
|
340
|
+
precision
|
341
|
+
eint exponential integral of object
|
342
|
+
li2 real part of the dilogarithm of object
|
343
|
+
gamma Gamma fucntion of object
|
344
|
+
lngamma logarithm of the Gamma function of object
|
345
|
+
digamma Digamma function of object (MPFR_VERSION >= "3.0.0")
|
346
|
+
zeta Reimann Zeta function of object
|
347
|
+
erf error function of object
|
348
|
+
erfc complementary error function of object
|
349
|
+
j0 first kind Bessel function of order 0 of object
|
350
|
+
j1 first kind Bessel function of order 1 of object
|
351
|
+
jn first kind Bessel function of order n of object
|
352
|
+
y0 second kind Bessel function of order 0 of object
|
353
|
+
y1 second kind Bessel function of order 1 of object
|
354
|
+
yn second kind Bessel function of order n of object
|
355
|
+
agm arithmetic-geometric mean
|
356
|
+
hypot
|
357
|
+
cos \
|
358
|
+
sin |
|
359
|
+
tan |
|
360
|
+
sin_cos |
|
361
|
+
sec |
|
362
|
+
csc |
|
363
|
+
cot |
|
364
|
+
acos |
|
365
|
+
asin |
|
366
|
+
atan | trigonometric functions
|
367
|
+
atan2 |
|
368
|
+
cosh | of the object
|
369
|
+
sinh |
|
370
|
+
tanh |
|
371
|
+
sinh_cosh |
|
372
|
+
sec |
|
373
|
+
csc |
|
374
|
+
cot |
|
375
|
+
acosh |
|
376
|
+
asinh |
|
377
|
+
atanh /
|
378
|
+
nan? \
|
379
|
+
infinite? | type of floating point number
|
380
|
+
finite? |
|
381
|
+
number? |
|
382
|
+
regular? / (MPFR_VERSION >= "3.0.0")
|
383
|
+
GMP::RandState
|
384
|
+
mpfr_urandomb(fixnum) get uniformly distributed random floating-point
|
385
|
+
number within 0 <= rop < 1
|
386
|
+
</code></pre>
|
387
|
+
|
388
|
+
<h2>Functional Mappings</h2>
|
389
|
+
|
390
|
+
<p>In order to align better with the GMP paradigms of using return arguments, I have started creating "functional mappings", singleton methods that map directly to functions in GMP. These methods take return arguments, so that passing an object to a functional mapping may change the object itself. For example:</p>
|
391
|
+
|
392
|
+
<pre><code>a = GMP::Z(0)
|
393
|
+
b = GMP::Z(13)
|
394
|
+
c = GMP::Z(17)
|
395
|
+
GMP::Z.add(a, b, c)
|
396
|
+
a #=> 30
|
397
|
+
</code></pre>
|
398
|
+
|
399
|
+
<p>Here's a fun list of all of the functional mappings written so far:</p>
|
400
|
+
|
401
|
+
<pre><code>GMP::Z
|
402
|
+
.abs .add .addmul .cdiv_q_2exp .cdiv_r_2exp .com
|
403
|
+
.congruent? .divexact .divisible? .fdiv_q_2exp .fdiv_r_2exp .lcm
|
404
|
+
.mul .mul_2exp
|
405
|
+
.neg .nextprime .sqrt .sub .submul .tdiv_q_2exp
|
406
|
+
.tdiv_r_2exp
|
407
|
+
</code></pre>
|
408
|
+
|
409
|
+
<h2>Documentation</h2>
|
410
|
+
|
411
|
+
<ul>
|
412
|
+
<li><a href="https://github.com/srawlins/gmp">This README</a></li>
|
413
|
+
<li>Loren Segal and the guys at RubyGems.org are badasses: <a href="http://rubydoc.info/gems/gmp/frames">YARDoc</a>.</li>
|
414
|
+
<li>There should be a manual.pdf <a href="https://github.com/srawlins/gmp/blob/master/manual.pdf">here</a>. I spend waaay too much time working on this, but it looks very pretty.</li>
|
415
|
+
<li><a href="https://github.com/srawlins/gmp/blob/master/CHANGELOG">CHANGELOG</a></li>
|
416
|
+
</ul>
|
417
|
+
|
418
|
+
|
419
|
+
<h2>Testing</h2>
|
420
|
+
|
421
|
+
<p>Tests can be run with:</p>
|
422
|
+
|
423
|
+
<pre><code>cd test
|
424
|
+
ruby unit_tests.rb
|
425
|
+
</code></pre>
|
426
|
+
|
427
|
+
<p>If you have the unit_test gem installed, all tests should pass. Otherwise, one test may error. I imagine there is a bug in Ruby's built-in <code>Test::Unit</code> package that is fixed with the unit_test gem.</p>
|
428
|
+
|
429
|
+
<h2>Known Issues</h2>
|
430
|
+
|
431
|
+
<ul>
|
432
|
+
<li>Don't call <code>GMP::RandState(:lc_2exp_size)</code>. Give a 2nd arg.</li>
|
433
|
+
<li>Don't use multiple assignment (<code>a = b = GMP::Z(0)</code>) with functional mappings.</li>
|
434
|
+
<li>JRuby has some interesting bugs and flickering tests. GMP::Z(GMP::GMP_NUMB_MAX) for example, blows up.</li>
|
435
|
+
<li>MPFR 3.1.0 breaks some of the random tests. This is because of a known change in MPFR. I just need my tests to become aware of the change.</li>
|
436
|
+
</ul>
|
437
|
+
|
438
|
+
|
439
|
+
<h2>Precision</h2>
|
440
|
+
|
441
|
+
<p>Precision can be explicitely set as second argument for <code>GMP::F.new()</code>. If there is no explicit precision, highest precision of all <code>GMP::F</code> arguments is used. That doesn't ensure that result will be exact. For details, consult any paper about floating point arithmetics.</p>
|
442
|
+
|
443
|
+
<p>Default precision can be explicitely set by passing <code>0</code> as the second argument for to <code>GMP::F.new()</code>. In particular, you can set precision of copy of <code>GMP::F</code> object by:</p>
|
444
|
+
|
445
|
+
<pre><code>new_obj = GMP::F.new(old_obj, 0)
|
446
|
+
</code></pre>
|
447
|
+
|
448
|
+
<p>Precision argument, and default_precision will be rounded up to whatever GMP thinks is appropriate.</p>
|
449
|
+
|
450
|
+
<h2>Benchmarking</h2>
|
451
|
+
|
452
|
+
<p>"GMP is carefully designed to be as fast as possible." Therefore, I believe it is very important for GMP, and its various language bindings to be benchmarked. In recent years, the GMP team developed GMPbench, an elegant, weighted benchmark. Currently, they maintain a list of recent benchmark <a href="http://www.gmplib.org/gmpbench.html">results</a>, broken down by CPU, CPU freq, ABI, and compiler flags; GMPbench compares different processor's performance against eachother, rather than GMP against other bignum libraries, or comparing different versions of GMP.</p>
|
453
|
+
|
454
|
+
<p>I intend to build a plug-in to GMPbench that will test the ruby gmp gem. The results of this benchmark should be directly comparable with the results of GMP (on same CPU, etc.). Rather than write a benchmark from the ground up, or try to emulate what GMPbench does, a plug-in will allow for this type of comparison. And in fact, GMPbench is (perhaps intentionally) written perfectly to allow for plugging in.</p>
|
455
|
+
|
456
|
+
<p>Various scores are derived from GMPbench by running the <code>runbench</code> script. This script compiles and runs various individual programs that measure the performance of base functions, such as multiply, and app functions such as rsa.</p>
|
457
|
+
|
458
|
+
<p>The gmp gem benchmark uses the GMPbench framework (that is, runbench, gexpr, and the timing methods), and plugs in ruby scripts as the individual programs. Right now, there are only four (of six) such plugged in ruby scripts:</p>
|
459
|
+
|
460
|
+
<ul>
|
461
|
+
<li>multiply - measures performance of multiplying (or squaring) <code>GMP::Z</code> objects whose size (in bits) is given by one or two operands.</li>
|
462
|
+
<li>divide - measures performance of dividing two <code>GMP::Z</code> objects (using <code>tdiv</code>) whose size (in bits) is given by two operands.</li>
|
463
|
+
<li>gcd - measure...</li>
|
464
|
+
<li>rsa - measures performance of using RSA to sign messages. The size of <code>pq</code>, the product of the two co-prime <code>GMP::Z</code> objects, <code>p</code> and <code>q</code>, is given by one operand.</li>
|
465
|
+
</ul>
|
466
|
+
|
467
|
+
|
468
|
+
<p><strong>insert table here</strong></p>
|
469
|
+
|
470
|
+
<p>My guess is that the increase in ruby gmp gem overhead is caused by increased efficiency in GMP; the inefficiencies of the gmp gem are relatively greater.</p>
|
471
|
+
|
472
|
+
<h2>Todo</h2>
|
473
|
+
|
474
|
+
<ul>
|
475
|
+
<li><code>GMP::Z#to_d_2exp</code>, <code>#congruent?</code>, <code>#rootrem</code>, <code>#lcm</code>, <code>#kronecker</code>, <code>#bin</code>, <code>#fib2</code>, <code>#lucnum</code>, <code>#lucnum2</code>, <code>#hamdist</code>, <code>#combit</code>, <code>#fits_x?</code></li>
|
476
|
+
<li><code>GMP::Q#to_s(base)</code>, <code>GMP::F#to_s(base)</code> (test it!)</li>
|
477
|
+
<li>benchmark gcdext, pi</li>
|
478
|
+
<li>a butt-load of functional mappings. 47-ish sets.</li>
|
479
|
+
<li>use Rake use Rake use Rake</li>
|
480
|
+
<li>investigate possible memory leaks when using <code>GMP::Q(22/7)</code> for example</li>
|
481
|
+
<li>beef up <code>r_gmpq_initialize</code>; I don't like to rely on <code>mpz_set_value</code>.</li>
|
482
|
+
<li>finish compile-results.rb</li>
|
483
|
+
<li>New in MPFR 3.1.0: mpfr_frexp, mpfr_grandom, mpfr_z_sub, divide-by-zero exception (?)</li>
|
484
|
+
</ul>
|
485
|
+
|
486
|
+
|
487
|
+
<p>The below are inherited from Tomasz. I will go through these and see which are
|
488
|
+
still relevant, and which I understand.</p>
|
489
|
+
|
490
|
+
<ul>
|
491
|
+
<li><code>mpz_fits_*</code> and 31 vs. 32 integer variables</li>
|
492
|
+
<li>fix all sign issues (don't know what these are)</li>
|
493
|
+
<li><code>to_s</code> vs. <code>inspect</code></li>
|
494
|
+
<li>check if <code>mpz_addmul_ui</code> would optimize some statements</li>
|
495
|
+
<li>some system that allows using denref and numref as normal ruby objects</li>
|
496
|
+
<li>takeover code that replaces all <code>Bignums</code> with <code>GMP::Z</code></li>
|
497
|
+
<li>better bignum parser (how? <code>to_s</code> seems good to me.)</li>
|
498
|
+
<li>zero-copy method for strings generation</li>
|
499
|
+
<li>benchmarks against Python GMP and Perl GMP</li>
|
500
|
+
<li><code>dup</code> methods</li>
|
501
|
+
<li>integrate <code>F</code> into system</li>
|
502
|
+
<li>should <code>Z.\[\]</code> bits be 0/1 or true/false, 0 is true, which might surprise users</li>
|
503
|
+
<li><code>any2small_integer()</code></li>
|
504
|
+
<li>check asm output, especially local memory efficiency (uh... no)</li>
|
505
|
+
<li>it might be better to use 'register' for some local variables (uh... no)</li>
|
506
|
+
<li>powm with negative exponents</li>
|
507
|
+
<li>check if different sorting of operatations gives better cache usage</li>
|
508
|
+
<li><code>GMP::\*</code> op <code>RubyFloat</code> and <code>RubyFloat</code> op <code>GMP::\*</code></li>
|
509
|
+
<li>sort checks</li>
|
510
|
+
</ul>
|
511
|
+
|