gmp 0.5.47 → 0.6.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -0
- data/README.markdown +10 -31
- data/benchmark/benchmark-results-5.0.5_1.9.3_0.6.7.ods +0 -0
- data/ext/gmp.c +36 -3
- data/ext/gmpbench_timing.c +9 -9
- data/ext/gmpf.c +83 -12
- data/ext/gmprandstate.c +14 -15
- data/ext/gmpz.c +145 -30
- data/ext/mprnd.c +7 -7
- data/ext/ruby_gmp.h +2 -2
- data/lib/gmp.rb +22 -1
- data/manual.pdf +0 -0
- data/manual.tex +4 -108
- data/performance.html +763 -0
- data/performance.md +321 -0
- data/performance.pdf +0 -0
- data/test/gmp_tlcm.rb +67 -0
- data/test/gmp_tprintf.rb +124 -0
- data/test/tc_division.rb +3 -3
- data/test/tc_f_arithmetics_coersion.rb +2 -2
- data/test/tc_f_to_s.rb +72 -0
- data/test/tc_mpfr_integer.rb +20 -0
- data/test/tc_mpfr_random.rb +61 -26
- data/test/test_helper.rb +1 -1
- data/test/unit_tests.rb +3 -0
- metadata +51 -57
- data/benchmark/COPYING +0 -674
- data/benchmark/README +0 -75
- data/benchmark/divide +0 -34
- data/benchmark/gcd +0 -38
- data/benchmark/gexpr.c +0 -359
- data/benchmark/multiply +0 -44
- data/benchmark/multiply.fnl +0 -47
- data/benchmark/multiply.gc +0 -57
- data/benchmark/pi +0 -126
- data/benchmark/rsa +0 -93
- data/benchmark/runbench +0 -147
- data/benchmark/srb.sh +0 -21
- data/benchmark/version +0 -1
data/CHANGELOG
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
0.6.7:
|
2
2
|
* Added 9th set of Functional Mappings: GMP::Z.divisible?
|
3
3
|
* Added 11th set of Functional Mappings: GMP::Z.congruent?
|
4
|
+
* Added GMP::sprintf for Ruby 1.9.x (requires Oniguruma regular expressions)
|
5
|
+
* Added optional parameter to GMP::F#to_s to allow a base to be passed in
|
6
|
+
* Finally added a rake file. My workflow now consists largely of:
|
7
|
+
rvm use _some_ruby_
|
8
|
+
rake make
|
9
|
+
* Added tests for GMP::F#to_s
|
10
|
+
* Added GMP::F#integer?
|
11
|
+
* Fixed tests for MPFR 3.1's PRNG
|
12
|
+
* Completely reorganized the benchmarks
|
13
|
+
* Added new performance.md, performance.html, and performance.pdf, a reworked benchmarking report
|
14
|
+
* Added GMP::Z#lcm, with tests
|
15
|
+
* Added an alloc_func, so that now GMP::Z#dup and GMP::Z#clone work
|
16
|
+
* Added GMP::Z#gcdext2, which only calculates g and s, for as + bt = g
|
4
17
|
|
5
18
|
0.5.47:
|
6
19
|
* Probably last release before 0.6.7
|
data/README.markdown
CHANGED
@@ -48,7 +48,7 @@ paragraph at [their homepage](http://gmplib.org/#WHAT):
|
|
48
48
|
> contributors to sign paperwork where they allow us to distribute their work."
|
49
49
|
|
50
50
|
Only GMP 4 or newer is supported. The following environments have been tested
|
51
|
-
by me: gmp gem 0.5.
|
51
|
+
by me: gmp gem 0.5.47 on:
|
52
52
|
|
53
53
|
<table border="1">
|
54
54
|
<tr>
|
@@ -97,20 +97,15 @@ by me: gmp gem 0.5.41 on:
|
|
97
97
|
GMP 5.0.1 (3.0.0)</td>
|
98
98
|
</tr>
|
99
99
|
<tr>
|
100
|
-
<td rowspan="4">Mac OS X 10.6.
|
100
|
+
<td rowspan="4">Mac OS X 10.6.8 on x86_64 (64-bit)</td>
|
101
101
|
<td>(MRI) Ruby 1.8.7</td>
|
102
102
|
<td>GMP 4.3.2 (2.4.2)<br />
|
103
|
-
GMP 5.0.
|
103
|
+
GMP 5.0.5 (3.1.1)</td>
|
104
104
|
</tr>
|
105
105
|
<tr>
|
106
|
-
<td>(MRI) Ruby 1.9.
|
107
|
-
<td>GMP 4.3.2 (2.4.2)<br />
|
108
|
-
GMP 5.0.1 (3.0.0)</td>
|
109
|
-
</tr>
|
110
|
-
<tr>
|
111
|
-
<td>(MRI) Ruby 1.9.2</td>
|
106
|
+
<td>(MRI) Ruby 1.9.3</td>
|
112
107
|
<td>GMP 4.3.2 (2.4.2)<br />
|
113
|
-
GMP 5.0.
|
108
|
+
GMP 5.0.5 (3.1.1)</td>
|
114
109
|
</tr>
|
115
110
|
<tr>
|
116
111
|
<td>(RBX) Rubinius 1.1.0</td>
|
@@ -278,7 +273,8 @@ Methods
|
|
278
273
|
certainly prime
|
279
274
|
nextprime next *probable* prime
|
280
275
|
nextprime! change the object into its next *probable* prime
|
281
|
-
gcd, gcdext
|
276
|
+
gcd, gcdext, gcdext2 greatest common divisor
|
277
|
+
lcm least common multiple
|
282
278
|
invert(m) invert mod m
|
283
279
|
jacobi jacobi symbol
|
284
280
|
legendre legendre symbol
|
@@ -424,7 +420,6 @@ Known Issues
|
|
424
420
|
* Don't call `GMP::RandState(:lc_2exp_size)`. Give a 2nd arg.
|
425
421
|
* Don't use multiple assignment (`a = b = GMP::Z(0)`) with functional mappings.
|
426
422
|
* JRuby has some interesting bugs and flickering tests. GMP::Z(GMP::GMP_NUMB_MAX) for example, blows up.
|
427
|
-
* 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.
|
428
423
|
|
429
424
|
Precision
|
430
425
|
---------
|
@@ -440,31 +435,15 @@ Precision argument, and default_precision will be rounded up to whatever GMP thi
|
|
440
435
|
Benchmarking
|
441
436
|
------------
|
442
437
|
|
443
|
-
|
444
|
-
|
445
|
-
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.
|
446
|
-
|
447
|
-
Various scores are derived from GMPbench by running the `runbench` 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.
|
448
|
-
|
449
|
-
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:
|
450
|
-
|
451
|
-
* multiply - measures performance of multiplying (or squaring) `GMP::Z` objects whose size (in bits) is given by one or two operands.
|
452
|
-
* divide - measures performance of dividing two `GMP::Z` objects (using `tdiv`) whose size (in bits) is given by two operands.
|
453
|
-
* gcd - measure...
|
454
|
-
* rsa - measures performance of using RSA to sign messages. The size of `pq`, the product of the two co-prime `GMP::Z` objects, `p` and `q`, is given by one operand.
|
455
|
-
|
456
|
-
**insert table here**
|
457
|
-
|
458
|
-
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.
|
438
|
+
Please see [performance](performance.md)
|
459
439
|
|
460
440
|
Todo
|
461
441
|
----
|
462
442
|
|
463
|
-
* `GMP::Z#to_d_2exp`, `#congruent?`, `#rootrem`, `#
|
443
|
+
* `GMP::Z#to_d_2exp`, `#congruent?`, `#rootrem`, `#kronecker`, `#bin`, `#fib2`, `#lucnum`, `#lucnum2`, `#hamdist`, `#combit`, `#fits_x?`
|
464
444
|
* `GMP::Q#to_s(base)`, `GMP::F#to_s(base)` (test it!)
|
465
|
-
* benchmark
|
445
|
+
* benchmark pi
|
466
446
|
* a butt-load of functional mappings. 47-ish sets.
|
467
|
-
* use Rake use Rake use Rake
|
468
447
|
* investigate possible memory leaks when using `GMP::Q(22/7)` for example
|
469
448
|
* beef up `r_gmpq_initialize`; I don't like to rely on `mpz_set_value`.
|
470
449
|
* finish compile-results.rb
|
Binary file
|
data/ext/gmp.c
CHANGED
@@ -55,6 +55,33 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
|
|
55
55
|
return Qnil;
|
56
56
|
}
|
57
57
|
|
58
|
+
VALUE r_gmpsg_sprintf2(VALUE klass, VALUE format, VALUE arg) {
|
59
|
+
VALUE res;
|
60
|
+
char *buffer;
|
61
|
+
char *format_str;
|
62
|
+
MP_INT *arg_val_z;
|
63
|
+
MP_RAT *arg_val_q;
|
64
|
+
MP_FLOAT *arg_val_f;
|
65
|
+
(void)klass;
|
66
|
+
format_str = StringValuePtr(format);
|
67
|
+
if (GMPZ_P(arg)) {
|
68
|
+
mpz_get_struct (arg, arg_val_z);
|
69
|
+
gmp_asprintf(&buffer, format_str, arg_val_z);
|
70
|
+
} else if (GMPQ_P(arg)) {
|
71
|
+
mpq_get_struct (arg, arg_val_q);
|
72
|
+
gmp_asprintf(&buffer, format_str, arg_val_q);
|
73
|
+
} else if (GMPF_P(arg)) {
|
74
|
+
mpf_get_struct (arg, arg_val_f);
|
75
|
+
gmp_asprintf(&buffer, format_str, arg_val_f);
|
76
|
+
} else {
|
77
|
+
return format;
|
78
|
+
}
|
79
|
+
|
80
|
+
res = rb_str_new2(buffer);
|
81
|
+
free(buffer);
|
82
|
+
return res;
|
83
|
+
}
|
84
|
+
|
58
85
|
#ifdef MPFR
|
59
86
|
mp_rnd_t r_get_rounding_mode(VALUE rnd)
|
60
87
|
{
|
@@ -108,11 +135,17 @@ void Init_gmp() {
|
|
108
135
|
rb_define_const(mGMP, "GMP_BITS_PER_LIMB", INT2FIX(mp_bits_per_limb));
|
109
136
|
rb_define_const(mGMP, "GMP_NUMB_MAX", ULONG2NUM(GMP_NUMB_MAX));
|
110
137
|
#ifdef MPFR
|
111
|
-
rb_define_const(mGMP, "MPFR_VERSION",
|
138
|
+
rb_define_const(mGMP, "MPFR_VERSION", rb_str_new2(MPFR_VERSION_STRING));
|
139
|
+
rb_define_const(mGMP, "MPFR_VERSION_MAJOR", INT2FIX(MPFR_VERSION_MAJOR));
|
140
|
+
rb_define_const(mGMP, "MPFR_VERSION_MINOR", INT2FIX(MPFR_VERSION_MINOR));
|
141
|
+
rb_define_const(mGMP, "MPFR_VERSION_PATCHLEVEL", INT2FIX(MPFR_VERSION_PATCHLEVEL));
|
112
142
|
rb_define_const(mGMP, "MPFR_PREC_MIN", INT2FIX(MPFR_PREC_MIN));
|
113
143
|
rb_define_const(mGMP, "MPFR_PREC_MAX", INT2FIX(MPFR_PREC_MAX));
|
114
144
|
#endif /* MPFR */
|
115
145
|
|
146
|
+
// Formatted Output Functions
|
147
|
+
rb_define_singleton_method(mGMP, "sprintf2", r_gmpsg_sprintf2, 2);
|
148
|
+
|
116
149
|
cGMP_Z = rb_define_class_under(mGMP, "Z", rb_cInteger);
|
117
150
|
init_gmpz ();
|
118
151
|
rb_define_method(cGMP_Z, "coerce", r_gmpz_coerce, 1);
|
@@ -135,10 +168,10 @@ void Init_gmp() {
|
|
135
168
|
rb_define_method (cGMP_F, "coerce", r_gmpf_coerce, 1); // new method - testing
|
136
169
|
|
137
170
|
/* rb_define_method(cGMP_F, "cmpabs", r_gmpf_cmpabs, 1);*/
|
138
|
-
|
171
|
+
|
139
172
|
cGMP_RandState = rb_define_class_under (mGMP, "RandState", rb_cObject);
|
140
173
|
init_gmprandstate ();
|
141
|
-
|
174
|
+
|
142
175
|
init_gmpbench_timing ();
|
143
176
|
|
144
177
|
// more
|
data/ext/gmpbench_timing.c
CHANGED
@@ -10,11 +10,11 @@
|
|
10
10
|
__times = 1; \
|
11
11
|
{func;} \
|
12
12
|
do { \
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
__times <<= 1; \
|
14
|
+
__t0 = FIX2INT(r_gmpmod_cputime ()); \
|
15
|
+
for (__t = 0; __t < __times; __t++) \
|
16
|
+
{func;} \
|
17
|
+
__tmp = FIX2INT(r_gmpmod_cputime ()) - __t0; \
|
18
18
|
} while (__tmp < 250); \
|
19
19
|
(t) = (double) __tmp / __times; \
|
20
20
|
} while (0)
|
@@ -22,7 +22,7 @@
|
|
22
22
|
/* Return user CPU time measured in milliseconds. */
|
23
23
|
#if !defined (__sun) \
|
24
24
|
&& (defined (USG) || defined (__SVR4) || defined (_UNICOS) \
|
25
|
-
|
25
|
+
|| defined (__hpux) || defined (_WIN32))
|
26
26
|
#include <time.h>
|
27
27
|
|
28
28
|
int
|
@@ -55,12 +55,12 @@ r_gmpmod_cputime (VALUE self)
|
|
55
55
|
VALUE
|
56
56
|
r_gmpmod_time (VALUE self)
|
57
57
|
{
|
58
|
-
(void)self;
|
59
58
|
long int __t0, __times, __t, __tmp;
|
59
|
+
(void)self;
|
60
60
|
__times = 1;
|
61
|
-
|
61
|
+
|
62
62
|
rb_need_block();
|
63
|
-
|
63
|
+
|
64
64
|
rb_yield (Qnil);
|
65
65
|
do {
|
66
66
|
__times <<= 1;
|
data/ext/gmpf.c
CHANGED
@@ -75,6 +75,7 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
75
75
|
MP_FLOAT *self_val, *arg_val_f;
|
76
76
|
unsigned long prec = 0;
|
77
77
|
VALUE arg;
|
78
|
+
int base = 10;
|
78
79
|
|
79
80
|
mpf_get_struct (self, self_val);
|
80
81
|
|
@@ -109,7 +110,6 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
109
110
|
prec = mpf_get_prec (arg_val_f);
|
110
111
|
}
|
111
112
|
#ifdef MPFR
|
112
|
-
int base = 10;
|
113
113
|
if (prec == 0)
|
114
114
|
mpfr_init (self_val);
|
115
115
|
else
|
@@ -128,7 +128,7 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
128
128
|
}
|
129
129
|
}
|
130
130
|
if (argc == 4) {
|
131
|
-
// FIGURE IT OUT. ACCEPT A ROUNDING MODE!
|
131
|
+
// TODO: FIGURE IT OUT. ACCEPT A ROUNDING MODE!
|
132
132
|
}
|
133
133
|
|
134
134
|
mpf_set_value2 (self_val, arg, base);
|
@@ -260,19 +260,60 @@ VALUE r_gmpf_to_d(VALUE self)
|
|
260
260
|
*
|
261
261
|
* Returns the decimal representation of _x_, as a String.
|
262
262
|
*/
|
263
|
-
VALUE r_gmpf_to_s(VALUE self)
|
263
|
+
VALUE r_gmpf_to_s(int argc, VALUE *argv, VALUE self)
|
264
264
|
{
|
265
265
|
MP_FLOAT *self_val;
|
266
266
|
char *str, *str2;
|
267
267
|
VALUE res;
|
268
268
|
mp_exp_t exponent;
|
269
269
|
|
270
|
+
VALUE base;
|
271
|
+
int base_val = 10;
|
272
|
+
ID base_id;
|
273
|
+
const char * bin_base = "bin"; /* binary */
|
274
|
+
const char * oct_base = "oct"; /* octal */
|
275
|
+
const char * dec_base = "dec"; /* decimal */
|
276
|
+
const char * hex_base = "hex"; /* hexadecimal */
|
277
|
+
ID bin_base_id = rb_intern(bin_base);
|
278
|
+
ID oct_base_id = rb_intern(oct_base);
|
279
|
+
ID dec_base_id = rb_intern(dec_base);
|
280
|
+
ID hex_base_id = rb_intern(hex_base);
|
281
|
+
|
270
282
|
mpf_get_struct(self, self_val);
|
271
283
|
|
284
|
+
/* TODO: accept a second optional argument, n_digits */
|
285
|
+
rb_scan_args (argc, argv, "01", &base);
|
286
|
+
|
287
|
+
/* The entire following stanza is determining the base. */
|
288
|
+
if (NIL_P (base)) { base = INT2FIX (10); } /* default value */
|
289
|
+
if (FIXNUM_P (base)) {
|
290
|
+
base_val = FIX2INT (base);
|
291
|
+
if ((base_val >= 2 && base_val <= 62) ||
|
292
|
+
(base_val >= -36 && base_val <= -2)) {
|
293
|
+
/* good base */
|
294
|
+
} else {
|
295
|
+
base_val = 10;
|
296
|
+
rb_raise (rb_eRangeError, "base must be within [2, 62] or [-36, -2].");
|
297
|
+
}
|
298
|
+
} else if (SYMBOL_P (base)) {
|
299
|
+
base_id = rb_to_id (base);
|
300
|
+
if (base_id == bin_base_id) {
|
301
|
+
base_val = 2;
|
302
|
+
} else if (base_id == oct_base_id) {
|
303
|
+
base_val = 8;
|
304
|
+
} else if (base_id == dec_base_id) {
|
305
|
+
base_val = 10;
|
306
|
+
} else if (base_id == hex_base_id) {
|
307
|
+
base_val = 16;
|
308
|
+
} else {
|
309
|
+
base_val = 10; /* TODO: should raise an exception here. */
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
272
313
|
//mpfr_sprintf(str, "%Rf", self_val);
|
273
314
|
//res = rb_str_new2(str);
|
274
315
|
|
275
|
-
str = mpfr_get_str(NULL, &exponent,
|
316
|
+
str = mpfr_get_str(NULL, &exponent, base_val, 0, self_val, __gmp_default_rounding_mode);
|
276
317
|
if ((strcmp(str, "NaN") == 0) ||
|
277
318
|
(strcmp(str, "Inf") == 0) ||
|
278
319
|
(strcmp(str, "-Inf") == 0))
|
@@ -288,7 +329,7 @@ VALUE r_gmpf_to_s(VALUE self)
|
|
288
329
|
res = rb_str_new2(str2);
|
289
330
|
mpfr_free_str(str2);
|
290
331
|
}
|
291
|
-
|
332
|
+
|
292
333
|
mpfr_free_str(str);
|
293
334
|
return res;
|
294
335
|
}
|
@@ -938,12 +979,12 @@ static VALUE r_gmpfr_##name(VALUE self) \
|
|
938
979
|
#define MPFR_CONST_FUNCTION(name) \
|
939
980
|
VALUE r_gmpfrsg_##name(int argc, VALUE *argv, VALUE self) \
|
940
981
|
{ \
|
941
|
-
(void)self; \
|
942
982
|
MP_FLOAT *res_val; \
|
943
983
|
VALUE res; \
|
944
984
|
VALUE rnd_mode, prec; \
|
945
985
|
mp_rnd_t rnd_mode_val; \
|
946
986
|
mpfr_prec_t prec_val; \
|
987
|
+
(void)self; \
|
947
988
|
\
|
948
989
|
rb_scan_args (argc, argv, "02", &rnd_mode, &prec); \
|
949
990
|
\
|
@@ -1012,11 +1053,36 @@ MPFR_SINGLE_LONG_FUNCTION(yn)
|
|
1012
1053
|
MPFR_SINGLE_MPF_FUNCTION(agm)
|
1013
1054
|
MPFR_SINGLE_MPF_FUNCTION(hypot)
|
1014
1055
|
|
1056
|
+
//VALUE r_gmpfrsg_sprintf(int argc, VALUE *argv, VALUE self)
|
1057
|
+
//rb_scan_args (argc, argv, "1*", &format, &list);
|
1058
|
+
VALUE r_gmpfrsg_sprintf2(VALUE klass, VALUE format, VALUE arg) {
|
1059
|
+
VALUE res;
|
1060
|
+
char *buffer;
|
1061
|
+
char *format_str;
|
1062
|
+
MP_INT *arg_val_z;
|
1063
|
+
MP_FLOAT *arg_val_f;
|
1064
|
+
(void)klass;
|
1065
|
+
format_str = StringValuePtr(format);
|
1066
|
+
if (GMPZ_P(arg)) {
|
1067
|
+
mpz_get_struct (arg, arg_val_z);
|
1068
|
+
mpfr_asprintf(&buffer, format_str, arg_val_z);
|
1069
|
+
} else if (GMPF_P(arg)) {
|
1070
|
+
mpf_get_struct (arg, arg_val_f);
|
1071
|
+
mpfr_asprintf(&buffer, format_str, arg_val_f);
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
res = rb_str_new2(buffer);
|
1075
|
+
free(buffer);
|
1076
|
+
return res;
|
1077
|
+
}
|
1078
|
+
|
1015
1079
|
MPFR_CONST_FUNCTION(const_log2)
|
1016
1080
|
MPFR_CONST_FUNCTION(const_pi)
|
1017
1081
|
MPFR_CONST_FUNCTION(const_euler)
|
1018
1082
|
MPFR_CONST_FUNCTION(const_catalan)
|
1019
1083
|
|
1084
|
+
MPFR_SINGLE_BOOLEAN_FUNCTION(integer_p)
|
1085
|
+
|
1020
1086
|
MPFR_SINGLE_BOOLEAN_FUNCTION(nan_p)
|
1021
1087
|
MPFR_SINGLE_BOOLEAN_FUNCTION(inf_p)
|
1022
1088
|
static VALUE r_gmpfr_fin_p(VALUE self)
|
@@ -1084,8 +1150,8 @@ static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
|
|
1084
1150
|
|
1085
1151
|
VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
|
1086
1152
|
{
|
1087
|
-
(void)klass;
|
1088
1153
|
const char *rounding_string_val;
|
1154
|
+
(void)klass;
|
1089
1155
|
rounding_string_val = mpfr_print_rnd_mode (mpfr_get_default_rounding_mode ());
|
1090
1156
|
if ( rounding_string_val == NULL ) {
|
1091
1157
|
return Qnil;
|
@@ -1097,8 +1163,8 @@ VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
|
|
1097
1163
|
|
1098
1164
|
VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
|
1099
1165
|
{
|
1100
|
-
(void)klass;
|
1101
1166
|
VALUE mode;
|
1167
|
+
(void)klass;
|
1102
1168
|
if (GMPRND_P(arg)) {
|
1103
1169
|
mode = rb_funcall (arg, rb_intern("mode"), 0);
|
1104
1170
|
if (FIX2INT(mode) < 0 || FIX2INT(mode) > 3) {
|
@@ -1149,8 +1215,6 @@ VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec
|
|
1149
1215
|
return Qfalse;
|
1150
1216
|
}
|
1151
1217
|
|
1152
|
-
#endif
|
1153
|
-
|
1154
1218
|
|
1155
1219
|
/**********************************************************************
|
1156
1220
|
* Rounding Related Functions *
|
@@ -1168,6 +1232,8 @@ VALUE r_gmpfsg_mpfr_buildopt_decimal_p(VALUE klass)
|
|
1168
1232
|
return INT2FIX (mpfr_buildopt_decimal_p());
|
1169
1233
|
}
|
1170
1234
|
|
1235
|
+
#endif
|
1236
|
+
|
1171
1237
|
|
1172
1238
|
/**********************************************************************
|
1173
1239
|
* _unsorted_ *
|
@@ -1221,7 +1287,7 @@ void init_gmpf()
|
|
1221
1287
|
rb_define_method(cGMP_F, "prec_raw=", r_gmpf_set_prec_raw, 1);
|
1222
1288
|
|
1223
1289
|
// Converting Floats
|
1224
|
-
rb_define_method(cGMP_F, "to_s", r_gmpf_to_s,
|
1290
|
+
rb_define_method(cGMP_F, "to_s", r_gmpf_to_s, -1);
|
1225
1291
|
rb_define_method(cGMP_F, "to_d", r_gmpf_to_d, 0);
|
1226
1292
|
rb_define_alias(cGMP_F, "to_f", "to_d");
|
1227
1293
|
|
@@ -1257,7 +1323,8 @@ void init_gmpf()
|
|
1257
1323
|
rb_define_method(cGMP_F, "ceil", r_gmpf_ceil, 0);
|
1258
1324
|
rb_define_method(cGMP_F, "ceil!", r_gmpf_ceil_self, 0);
|
1259
1325
|
rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
|
1260
|
-
rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);
|
1326
|
+
rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);
|
1327
|
+
rb_define_method(cGMP_F, "trunc", r_gmpf_trunc, 0);
|
1261
1328
|
rb_define_method(cGMP_F, "trunc!", r_gmpf_trunc_self, 0);
|
1262
1329
|
|
1263
1330
|
|
@@ -1364,6 +1431,9 @@ void init_gmpf()
|
|
1364
1431
|
rb_define_method(cGMP_F, "hypot", r_gmpfr_hypot, -1);
|
1365
1432
|
// "ai", r_gmpfr_ai !! 3.0.0
|
1366
1433
|
|
1434
|
+
// Formatted Output Functions
|
1435
|
+
rb_define_singleton_method(cGMP_F, "sprintf2", r_gmpfrsg_sprintf2, 2);
|
1436
|
+
|
1367
1437
|
rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, -1);
|
1368
1438
|
rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, -1);
|
1369
1439
|
rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, -1);
|
@@ -1371,6 +1441,7 @@ void init_gmpf()
|
|
1371
1441
|
|
1372
1442
|
// Integer and Remainder Related Functions
|
1373
1443
|
// "integer?", r_gmpfr_integer_p
|
1444
|
+
rb_define_method(cGMP_F, "integer?", r_gmpfr_integer_p, 0);
|
1374
1445
|
|
1375
1446
|
// Rounding Related Functions
|
1376
1447
|
rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
|
data/ext/gmprandstate.c
CHANGED
@@ -47,14 +47,14 @@ VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
|
|
47
47
|
unsigned long c_val, m2exp_val;
|
48
48
|
unsigned long size_val;
|
49
49
|
int free_a_val = 0;
|
50
|
-
|
50
|
+
|
51
51
|
ID default_algorithm = rb_intern("default");
|
52
52
|
ID mt_algorithm = rb_intern("mt");
|
53
53
|
ID lc_2exp_algorithm = rb_intern("lc_2exp");
|
54
54
|
ID lc_2exp_size_algorithm = rb_intern("lc_2exp_size");
|
55
|
-
|
55
|
+
|
56
56
|
(void)klass;
|
57
|
-
|
57
|
+
|
58
58
|
mprandstate_make_struct(rs, rs_val);
|
59
59
|
rb_scan_args(argc, argv, "04", &algorithm, &arg2, &arg3, &arg4);
|
60
60
|
if (NIL_P(algorithm)) { algorithm_id = rb_intern("default"); } /* default value */
|
@@ -88,14 +88,13 @@ VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
|
|
88
88
|
size_val = NUM2LONG(arg2);
|
89
89
|
if (size_val > 128)
|
90
90
|
rb_raise(rb_eArgError, "size must be within [0..128]");
|
91
|
-
|
92
|
-
if (rv == 0)
|
91
|
+
if (gmp_randinit_lc_2exp_size (rs_val, size_val) == 0)
|
93
92
|
rb_raise(rb_eArgError, "could not gmp_randinit_lc_2exp_size with %lu", size_val);
|
94
93
|
}
|
95
|
-
|
94
|
+
|
96
95
|
if (free_a_val) { mpz_temp_free(a_val); }
|
97
96
|
rb_obj_call_init(rs, argc, argv);
|
98
|
-
|
97
|
+
|
99
98
|
return rs;
|
100
99
|
}
|
101
100
|
|
@@ -156,7 +155,7 @@ VALUE r_gmprandstate_seed(VALUE self, VALUE arg)
|
|
156
155
|
MP_INT *arg_val;
|
157
156
|
|
158
157
|
mprandstate_get_struct(self,self_val);
|
159
|
-
|
158
|
+
|
160
159
|
if (GMPZ_P(arg)) {
|
161
160
|
mpz_get_struct(arg,arg_val);
|
162
161
|
gmp_randseed(self_val, arg_val);
|
@@ -192,14 +191,14 @@ VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg)
|
|
192
191
|
VALUE res;
|
193
192
|
|
194
193
|
mprandstate_get_struct(self,self_val);
|
195
|
-
|
194
|
+
|
196
195
|
if (FIXNUM_P(arg)) {
|
197
196
|
mpz_make_struct_init(res, res_val);
|
198
197
|
mpz_urandomb(res_val, self_val, FIX2INT(arg));
|
199
198
|
} else {
|
200
199
|
typeerror(X);
|
201
200
|
}
|
202
|
-
|
201
|
+
|
203
202
|
return res;
|
204
203
|
}
|
205
204
|
|
@@ -221,7 +220,7 @@ VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
|
|
221
220
|
VALUE res;
|
222
221
|
|
223
222
|
mprandstate_get_struct(self,self_val);
|
224
|
-
|
223
|
+
|
225
224
|
if (GMPZ_P(arg)) {
|
226
225
|
mpz_get_struct(arg, arg_val);
|
227
226
|
} else if (FIXNUM_P(arg)) {
|
@@ -234,11 +233,11 @@ VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
|
|
234
233
|
} else {
|
235
234
|
typeerror_as(ZXB, "arg");
|
236
235
|
}
|
237
|
-
|
236
|
+
|
238
237
|
mpz_make_struct_init(res, res_val);
|
239
238
|
mpz_urandomm(res_val, self_val, arg_val);
|
240
239
|
if (free_arg_val) { mpz_temp_free(arg_val); }
|
241
|
-
|
240
|
+
|
242
241
|
return res;
|
243
242
|
}
|
244
243
|
|
@@ -260,14 +259,14 @@ VALUE r_gmprandstate_rrandomb(VALUE self, VALUE arg)
|
|
260
259
|
VALUE res;
|
261
260
|
|
262
261
|
mprandstate_get_struct(self,self_val);
|
263
|
-
|
262
|
+
|
264
263
|
if (FIXNUM_P(arg)) {
|
265
264
|
mpz_make_struct_init(res, res_val);
|
266
265
|
mpz_rrandomb(res_val, self_val, FIX2INT(arg));
|
267
266
|
} else {
|
268
267
|
typeerror(X);
|
269
268
|
}
|
270
|
-
|
269
|
+
|
271
270
|
return res;
|
272
271
|
}
|
273
272
|
|