gmp 0.6.43 → 0.6.47
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +15 -0
- data/README.markdown +23 -13
- data/ext/gmp.c +13 -6
- data/ext/gmpf.c +377 -166
- data/ext/gmpq.c +17 -17
- data/ext/gmprandstate.c +72 -23
- data/ext/ruby_gmp.h +35 -19
- data/manual.pdf +0 -0
- data/manual.tex +140 -5
- data/test/gmp_troot.rb +4 -0
- data/test/mpfr_tcbrt.rb +3 -3
- data/test/mpfr_tconst_euler.rb +15 -24
- data/test/mpfr_tfac.rb +49 -0
- data/test/mpfr_tfrexp.rb +47 -0
- data/test/tc_f_abs_neg.rb +28 -0
- data/test/tc_f_to_s.rb +29 -15
- data/test/tc_mpfr_cmp.rb +29 -0
- data/test/tc_mpfr_inf_nan_zero.rb +29 -0
- data/test/tc_mpfr_new_rounding.rb +126 -0
- data/test/tc_mpfr_random.rb +63 -3
- data/test/tc_sgn_neg_abs.rb +3 -3
- data/test/test_helper.rb +12 -3
- data/test/unit_tests.rb +8 -4
- metadata +10 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
0.6.47
|
2
|
+
* Fixed GMP::F#to_s when MPFR is not present. It now works, and accepts an
|
3
|
+
optional base argument, just like GMP::F#to_s does when MPFR _is_ present.
|
4
|
+
* Added new optional rounding mode argument to GMP::F.new(Fixnum),
|
5
|
+
GMP::F.new(Bignum), GMP::F.new(GMP::Z), GMP::F.new(GMP::Q),
|
6
|
+
GMP::F.new(Float), and GMP::F.new(GMP::F) with tests (MPFR only)
|
7
|
+
* Added MPFR method GMP::RandState.mpfr_urandom (mpfr_urandom) and tests
|
8
|
+
* Added MPFR methods GMP::F#lessgreater? and GMP::F#unordered?, with sanity
|
9
|
+
tests
|
10
|
+
* Added tests for GMP::F#abs and GMP::F#neg
|
11
|
+
* Added GMP::F.fac(n) (mpfr_fac_ui) and tests
|
12
|
+
* Added GMP::F.nan, GMP::F.inf, GMP::F.zero (MPFR >= 3.0.0), documentation, and simple tests
|
13
|
+
* Added GMP::F#frexp, documentation, and tests
|
14
|
+
* Fixed GMP::MPFR_RNDA
|
15
|
+
|
1
16
|
0.6.43
|
2
17
|
* Fixed compilation on OS X 10.9 Mavericks, using LLVM 5.0
|
3
18
|
* Added license: Apache v2
|
data/README.markdown
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
gmp
|
2
2
|
===
|
3
3
|
|
4
|
+
[![Build Status](https://travis-ci.org/srawlins/gmp.png?branch=master)](https://travis-ci.org/srawlins/gmp)
|
5
|
+
|
4
6
|
gmp is library providing Ruby bindings to GMP library. Here is the introduction
|
5
7
|
paragraph at [their homepage](http://gmplib.org/#WHAT):
|
6
8
|
|
@@ -158,12 +160,12 @@ as pi, are defined under class methods of GMP::F, listed below.
|
|
158
160
|
* `GMP::GMP_VERSION` - A string like "5.0.1"
|
159
161
|
* `GMP::GMP_CC` - The compiler used to compile GMP
|
160
162
|
* `GMP::GMP_CFLAGS` - The CFLAGS used to compile GMP
|
161
|
-
* `GMP::
|
163
|
+
* `GMP::GMP_BITS_PER_LIMB` The number of bits per limb
|
162
164
|
* `GMP::GMP_NUMB_MAX` - The maximum value that can be stored in the number part of a limb
|
163
165
|
|
164
166
|
if MPFR is available:
|
165
167
|
* `GMP::MPFR_VERSION` - A string like "2.4.2"
|
166
|
-
* `GMP::
|
168
|
+
* `GMP::MPFR_PREC_MIN` - The minimum precision available
|
167
169
|
* `GMP::MPFR_PREC_MAX` - The maximum precision available
|
168
170
|
* `GMP::GMP_RNDN` - The constant representing "round to nearest"
|
169
171
|
* `GMP::GMP_RNDZ` - The constant representing "round toward zero"
|
@@ -199,14 +201,13 @@ Numbers are created by using `new()`. Constructors can take following arguments:
|
|
199
201
|
GMP::Q.new(any GMP::Z initializer)
|
200
202
|
GMP::Q.new(any GMP::Z initializer, any GMP::Z initializer)
|
201
203
|
GMP::F.new()
|
202
|
-
GMP::F.new(GMP::Z, precision=0)
|
203
|
-
GMP::F.new(GMP::Q, precision=0)
|
204
|
-
GMP::F.new(GMP::F)
|
205
|
-
GMP::F.new(GMP::F, precision)
|
204
|
+
GMP::F.new(GMP::Z, precision=0, rounding_mode=default)
|
205
|
+
GMP::F.new(GMP::Q, precision=0, rounding_mode=default)
|
206
|
+
GMP::F.new(GMP::F, precision=0, rounding_mode=default)
|
206
207
|
GMP::F.new(String, precision=0)
|
207
|
-
GMP::F.new(Fixnum, precision=0)
|
208
|
-
GMP::F.new(Bignum, precision=0)
|
209
|
-
GMP::F.new(Float, precision=0)
|
208
|
+
GMP::F.new(Fixnum, precision=0, rounding_mode=default)
|
209
|
+
GMP::F.new(Bignum, precision=0, rounding_mode=default)
|
210
|
+
GMP::F.new(Float, precision=0, roundung_mode=default)
|
210
211
|
GMP::RandState.new(\[algorithm\] \[, algorithm_args\])
|
211
212
|
|
212
213
|
You can also call them as:
|
@@ -236,7 +237,7 @@ Methods
|
|
236
237
|
abs! in-place absolute value
|
237
238
|
coerce promotion of arguments
|
238
239
|
== equality test
|
239
|
-
|
240
|
+
<=>, >=, >, <=, < comparisions
|
240
241
|
class methods of GMP::Z
|
241
242
|
fac(n) factorial of n
|
242
243
|
2fac(n), double_fac(n) double factorial of n
|
@@ -312,6 +313,7 @@ Methods
|
|
312
313
|
class methods of GMP::F
|
313
314
|
default_prec get default precision
|
314
315
|
default_prec= set default precision
|
316
|
+
fac(n) new GMP::F, equal to factorial of n
|
315
317
|
GMP::F
|
316
318
|
prec get precision
|
317
319
|
floor,ceil,trunc nearest integer, GMP::F is returned, not GMP::Z
|
@@ -328,6 +330,9 @@ Methods
|
|
328
330
|
|
329
331
|
*only if MPFR is available*
|
330
332
|
class methods of GMP::F
|
333
|
+
nan returns NaN
|
334
|
+
inf(sign = 1) returns Inf or -Inf
|
335
|
+
zero(sign = 1) returns zero or -zero
|
331
336
|
const_log2 returns the natural log of 2
|
332
337
|
const_pi returns pi
|
333
338
|
const_euler returns euler
|
@@ -336,6 +341,9 @@ Methods
|
|
336
341
|
mpfr_buildopt_decimal_p returns whether MPFR was compiled with decimal
|
337
342
|
float support
|
338
343
|
GMP::F
|
344
|
+
frexp frexp
|
345
|
+
lessgreater?(y) x < y or y < x?
|
346
|
+
unordered?(y) either x or y is NaN?
|
339
347
|
sqrt square root of the object
|
340
348
|
rec_sqrt square root of the recprical of the object
|
341
349
|
cbrt cube root of the object
|
@@ -393,8 +401,10 @@ Methods
|
|
393
401
|
number? |
|
394
402
|
regular? / (MPFR_VERSION >= "3.0.0")
|
395
403
|
GMP::RandState
|
396
|
-
mpfr_urandomb(
|
397
|
-
|
404
|
+
mpfr_urandomb(prec = default) get uniformly distributed random floating-point
|
405
|
+
number within 0 <= rop < 1
|
406
|
+
mpfr_urandom(prec = default) get uniformly distributed random floating-point
|
407
|
+
number (MPFR_VERSION >= "3.0.0")
|
398
408
|
|
399
409
|
Functional Mappings
|
400
410
|
-------------------
|
@@ -584,7 +594,7 @@ Precision argument, and default_precision will be rounded up to whatever GMP thi
|
|
584
594
|
Benchmarking
|
585
595
|
------------
|
586
596
|
|
587
|
-
Please see [performance](https://github.com/srawlins/gmp/
|
597
|
+
Please see [performance](https://github.com/srawlins/gmp/raw/master/performance.2012.pdf) on GitHub.
|
588
598
|
|
589
599
|
License
|
590
600
|
-------
|
data/ext/gmp.c
CHANGED
@@ -117,17 +117,24 @@ VALUE r_gmpsg_sprintf2(VALUE klass, VALUE format, VALUE arg) {
|
|
117
117
|
mp_rnd_t r_get_rounding_mode(VALUE rnd)
|
118
118
|
{
|
119
119
|
VALUE mode;
|
120
|
-
|
121
|
-
|
120
|
+
int max_rnd;
|
121
|
+
|
122
|
+
#if MPFR_VERSION_MAJOR>2
|
123
|
+
max_rnd = 4;
|
124
|
+
#else
|
125
|
+
max_rnd = 3;
|
126
|
+
#endif
|
127
|
+
|
128
|
+
if (GMPRND_P (rnd)) {
|
122
129
|
mode = rb_funcall (rnd, rb_intern("mode"), 0);
|
123
|
-
if (FIX2INT(mode) < 0 || FIX2INT(mode) >
|
124
|
-
rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
|
130
|
+
if (FIX2INT (mode) < 0 || FIX2INT (mode) > max_rnd) {
|
131
|
+
rb_raise (rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
|
125
132
|
}
|
126
133
|
} else {
|
127
134
|
rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
128
135
|
}
|
129
|
-
|
130
|
-
switch (FIX2INT(mode)) {
|
136
|
+
|
137
|
+
switch (FIX2INT (mode)) {
|
131
138
|
case 0:
|
132
139
|
return GMP_RNDN;
|
133
140
|
case 1:
|
data/ext/gmpf.c
CHANGED
@@ -16,31 +16,31 @@
|
|
16
16
|
* Macros *
|
17
17
|
**********************************************************************/
|
18
18
|
|
19
|
-
#define DEFUN_FLOAT2FLOAT(fname,mpf_fname)
|
20
|
-
static VALUE r_gmpf_##fname(VALUE
|
21
|
-
{
|
22
|
-
MP_FLOAT *
|
23
|
-
VALUE
|
24
|
-
mpf_get_struct(
|
25
|
-
mpf_make_struct_init(
|
26
|
-
mpf_fname(
|
27
|
-
return
|
28
|
-
}
|
29
|
-
|
30
|
-
static VALUE r_gmpf_##fname##_self(VALUE self)
|
31
|
-
{
|
32
|
-
MP_FLOAT *self_val;
|
33
|
-
mpf_get_struct(self, self_val);
|
34
|
-
mpf_fname(self_val, self_val);
|
35
|
-
return Qnil;
|
19
|
+
#define DEFUN_FLOAT2FLOAT(fname,mpf_fname) \
|
20
|
+
static VALUE r_gmpf_##fname(VALUE self_val) \
|
21
|
+
{ \
|
22
|
+
MP_FLOAT *self, *res; \
|
23
|
+
VALUE res_val; \
|
24
|
+
mpf_get_struct (self_val, self); \
|
25
|
+
mpf_make_struct_init (res_val, res, mpf_get_prec(self)); \
|
26
|
+
mpf_fname (res, self); \
|
27
|
+
return res_val; \
|
28
|
+
} \
|
29
|
+
\
|
30
|
+
static VALUE r_gmpf_##fname##_self(VALUE self) \
|
31
|
+
{ \
|
32
|
+
MP_FLOAT *self_val; \
|
33
|
+
mpf_get_struct (self, self_val); \
|
34
|
+
mpf_fname (self_val, self_val); \
|
35
|
+
return Qnil; \
|
36
36
|
}
|
37
37
|
|
38
|
-
#define DEFUN_FLOAT_CMP(name,CMP_OP)
|
39
|
-
static VALUE r_gmpf_cmp_##name(VALUE
|
40
|
-
{
|
41
|
-
MP_FLOAT *
|
42
|
-
mpf_get_struct(self
|
43
|
-
return (mpf_cmp_value(
|
38
|
+
#define DEFUN_FLOAT_CMP(name,CMP_OP) \
|
39
|
+
static VALUE r_gmpf_cmp_##name(VALUE self_val, VALUE arg_val) \
|
40
|
+
{ \
|
41
|
+
MP_FLOAT *self; \
|
42
|
+
mpf_get_struct (self_val, self); \
|
43
|
+
return (mpf_cmp_value (self, arg_val) CMP_OP 0) ? Qtrue : Qfalse; \
|
44
44
|
}
|
45
45
|
|
46
46
|
|
@@ -50,10 +50,33 @@ static VALUE r_gmpf_cmp_##name(VALUE self, VALUE arg) \
|
|
50
50
|
|
51
51
|
/*
|
52
52
|
* call-seq:
|
53
|
-
* GMP::F.new(
|
53
|
+
* GMP::F.new(value)
|
54
|
+
* GMP::F.new(value, precision)
|
55
|
+
* GMP::F.new(value, precision, rounding_mode) (MPFR only)
|
56
|
+
* GMP::F.new(string_value, precision, base)
|
57
|
+
*
|
58
|
+
* Creates a new GMP::F floating-point number, with _value_ as its value,
|
59
|
+
* converting where necessary. _value_ must be an instance of one of the
|
60
|
+
* following classes:
|
54
61
|
*
|
55
|
-
*
|
56
|
-
*
|
62
|
+
* * Fixnum
|
63
|
+
* * Bignum
|
64
|
+
* * GMP::Z
|
65
|
+
* * Float
|
66
|
+
* * GMP::Q
|
67
|
+
* * GMP::F
|
68
|
+
* * String
|
69
|
+
*
|
70
|
+
* @example
|
71
|
+
* GMP::F.new(5) #=> 5
|
72
|
+
* GMP::F(3**41) #=> 0.36472996377170788e+20
|
73
|
+
* GMP::F(3**41, 32) #=> 0.36472996375e+20
|
74
|
+
* GMP::F(3**41, 32, GMP::GMP_RNDU) #=> 0.36472996384e+20
|
75
|
+
* GMP::F.new("20") #=> 20
|
76
|
+
* GMP::F.new("0x20") #=> 32
|
77
|
+
* GMP::F("111", 16) #=> 111
|
78
|
+
* GMP::F("111", 16, 2) #=> 7
|
79
|
+
* GMP::F("111", 16, 16) #=> 273
|
57
80
|
*/
|
58
81
|
VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass)
|
59
82
|
{
|
@@ -62,7 +85,7 @@ VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass)
|
|
62
85
|
(void)klass;
|
63
86
|
|
64
87
|
if (argc > 4)
|
65
|
-
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1 2, 3, or 4)", argc);
|
88
|
+
rb_raise(rb_eArgError, "wrong # of arguments (%d for 0, 1 2, 3, or 4)", argc);
|
66
89
|
|
67
90
|
mpf_make_struct (res, res_val);
|
68
91
|
rb_obj_call_init(res, argc, argv);
|
@@ -75,6 +98,9 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
75
98
|
MP_FLOAT *self_val, *arg_val_f;
|
76
99
|
unsigned long prec = 0;
|
77
100
|
VALUE arg;
|
101
|
+
#ifdef MPFR
|
102
|
+
mp_rnd_t rnd_mode_val;
|
103
|
+
#endif
|
78
104
|
int base = 10;
|
79
105
|
|
80
106
|
mpf_get_struct (self, self_val);
|
@@ -110,6 +136,8 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
110
136
|
prec = mpf_get_prec (arg_val_f);
|
111
137
|
}
|
112
138
|
#ifdef MPFR
|
139
|
+
rnd_mode_val = __gmp_default_rounding_mode;
|
140
|
+
|
113
141
|
if (prec == 0)
|
114
142
|
mpfr_init (self_val);
|
115
143
|
else
|
@@ -127,33 +155,45 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
127
155
|
rb_raise(rb_eTypeError, "base must be a Fixnum");
|
128
156
|
}
|
129
157
|
}
|
158
|
+
|
130
159
|
if (argc == 4) {
|
131
160
|
// TODO: FIGURE IT OUT. ACCEPT A ROUNDING MODE!
|
132
161
|
}
|
133
162
|
|
134
163
|
mpf_set_value2 (self_val, arg, base);
|
135
164
|
return Qnil;
|
165
|
+
} else { /* not STRING_P(argv[0]) */
|
166
|
+
if (argc == 3)
|
167
|
+
rnd_mode_val = r_get_rounding_mode (argv[2]);
|
136
168
|
}
|
137
169
|
|
138
|
-
|
170
|
+
if (GMPF_P (arg)) {
|
171
|
+
mpf_get_struct (arg, arg_val_f);
|
172
|
+
mpfr_set (self_val, arg_val_f, rnd_mode_val);
|
173
|
+
} else {
|
174
|
+
mpfr_set_value (self_val, arg, rnd_mode_val);
|
175
|
+
}
|
176
|
+
|
177
|
+
#else /* not MPFR */
|
139
178
|
(void)base;
|
140
179
|
|
141
180
|
if (prec == 0)
|
142
181
|
r_mpf_init (self_val);
|
143
182
|
else
|
144
183
|
r_mpf_init2 (self_val, prec);
|
145
|
-
#endif
|
146
184
|
|
147
185
|
if (GMPF_P(arg)) {
|
148
186
|
mpf_get_struct (arg, arg_val_f);
|
149
|
-
mpf_set(self_val, arg_val_f);
|
187
|
+
mpf_set (self_val, arg_val_f);
|
150
188
|
} else {
|
151
|
-
mpf_set_value(self_val, arg);
|
189
|
+
mpf_set_value (self_val, arg);
|
152
190
|
}
|
191
|
+
#endif
|
153
192
|
|
154
193
|
return Qnil;
|
155
194
|
}
|
156
195
|
|
196
|
+
#ifndef MPFR
|
157
197
|
/* don't pass GMP::F here, it should be handled separately */
|
158
198
|
void mpf_set_value(MP_FLOAT *self_val, VALUE arg)
|
159
199
|
{
|
@@ -161,68 +201,149 @@ void mpf_set_value(MP_FLOAT *self_val, VALUE arg)
|
|
161
201
|
MP_INT *arg_val_z;
|
162
202
|
int result;
|
163
203
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
result = mpfr_set_str(self_val, StringValuePtr(arg), 10, __gmp_default_rounding_mode);
|
204
|
+
if (GMPQ_P (arg)) {
|
205
|
+
mpq_get_struct (arg, arg_val_q);
|
206
|
+
r_mpf_set_q (self_val, arg_val_q);
|
207
|
+
} else if (GMPZ_P (arg)) {
|
208
|
+
mpz_get_struct (arg, arg_val_z);
|
209
|
+
r_mpf_set_z (self_val, arg_val_z);
|
210
|
+
} else if (FLOAT_P (arg)) {
|
211
|
+
r_mpf_set_d (self_val, NUM2DBL (arg));
|
212
|
+
} else if (FIXNUM_P (arg)) {
|
213
|
+
mpf_set_si (self_val, FIX2NUM (arg));
|
214
|
+
} else if (STRING_P (arg)) {
|
215
|
+
result = r_mpf_set_str (self_val, StringValuePtr (arg), 10);
|
177
216
|
if (result == -1) {
|
178
|
-
rb_raise(rb_eRuntimeError, "Badly formatted string");
|
217
|
+
rb_raise (rb_eRuntimeError, "Badly formatted string");
|
179
218
|
}
|
180
|
-
} else if (BIGNUM_P(arg)) {
|
219
|
+
} else if (BIGNUM_P (arg)) {
|
181
220
|
#if 1 /* GMP3 code */
|
182
|
-
mpz_temp_from_bignum(arg_val_z, arg);
|
183
|
-
r_mpf_set_z(self_val, arg_val_z);
|
184
|
-
mpz_temp_free(arg_val_z);
|
185
|
-
#endif
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
221
|
+
mpz_temp_from_bignum (arg_val_z, arg);
|
222
|
+
r_mpf_set_z (self_val, arg_val_z);
|
223
|
+
mpz_temp_free (arg_val_z);
|
224
|
+
#endif /* GMP3 code */
|
225
|
+
} else {
|
226
|
+
rb_raise (rb_eTypeError, "Don't know how to convert %s into GMP::F", rb_class2name (rb_class_of (arg)));
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
#else /* MPFR */
|
231
|
+
/* don't pass GMP::F here, it should be handled separately */
|
232
|
+
void mpfr_set_value(MP_FLOAT *self_val, VALUE arg, mp_rnd_t rnd_mode_val)
|
233
|
+
{
|
234
|
+
MP_RAT *arg_val_q;
|
235
|
+
MP_INT *arg_val_z;
|
236
|
+
int result;
|
237
|
+
|
238
|
+
if (GMPQ_P (arg)) {
|
239
|
+
mpq_get_struct (arg, arg_val_q);
|
240
|
+
r_mpfr_set_q (self_val, arg_val_q, rnd_mode_val);
|
241
|
+
} else if (GMPZ_P (arg)) {
|
242
|
+
mpz_get_struct (arg, arg_val_z);
|
243
|
+
r_mpfr_set_z (self_val, arg_val_z, rnd_mode_val);
|
244
|
+
} else if (FLOAT_P (arg)) {
|
245
|
+
mpfr_set_d (self_val, NUM2DBL (arg), rnd_mode_val);
|
246
|
+
} else if (TYPE (arg) == T_FIXNUM) {
|
247
|
+
mpfr_set_si (self_val, FIX2NUM (arg), rnd_mode_val);
|
197
248
|
} else if (STRING_P(arg)) {
|
198
|
-
result =
|
249
|
+
result = mpfr_set_str (self_val, StringValuePtr (arg), 10, rnd_mode_val);
|
199
250
|
if (result == -1) {
|
200
251
|
rb_raise(rb_eRuntimeError, "Badly formatted string");
|
201
252
|
}
|
202
|
-
} else if (BIGNUM_P(arg)) {
|
253
|
+
} else if (BIGNUM_P (arg)) {
|
203
254
|
#if 1 /* GMP3 code */
|
204
|
-
mpz_temp_from_bignum(arg_val_z, arg);
|
205
|
-
|
206
|
-
mpz_temp_free(arg_val_z);
|
207
|
-
#endif
|
208
|
-
#endif
|
255
|
+
mpz_temp_from_bignum (arg_val_z, arg);
|
256
|
+
r_mpfr_set_z (self_val, arg_val_z, rnd_mode_val);
|
257
|
+
mpz_temp_free (arg_val_z);
|
258
|
+
#endif /* GMP3 code */
|
209
259
|
} else {
|
210
|
-
rb_raise(rb_eTypeError, "Don't know how to convert %s into GMP::F", rb_class2name(rb_class_of(arg)));
|
260
|
+
rb_raise (rb_eTypeError, "Don't know how to convert %s into GMP::F", rb_class2name (rb_class_of (arg)));
|
211
261
|
}
|
212
262
|
}
|
213
263
|
|
214
|
-
#ifdef MPFR
|
215
264
|
void mpf_set_value2(MP_FLOAT *self_val, VALUE arg, int base)
|
216
265
|
{
|
217
266
|
int result;
|
218
267
|
|
219
|
-
|
268
|
+
/* TODO use rnd_mode_val */
|
269
|
+
result = mpfr_set_str (self_val, StringValuePtr (arg), base, __gmp_default_rounding_mode);
|
220
270
|
|
221
271
|
if (result == -1) {
|
222
|
-
rb_raise(rb_eRuntimeError, "Badly formatted string");
|
272
|
+
rb_raise (rb_eRuntimeError, "Badly formatted string");
|
223
273
|
}
|
224
274
|
}
|
225
|
-
|
275
|
+
|
276
|
+
/*
|
277
|
+
* call-seq:
|
278
|
+
* GMP::F.nan
|
279
|
+
*
|
280
|
+
* NaN, an instance of GMP::F
|
281
|
+
*/
|
282
|
+
VALUE r_gmpfsg_nan(VALUE klass)
|
283
|
+
{
|
284
|
+
MP_FLOAT *res;
|
285
|
+
VALUE res_val;
|
286
|
+
(void)klass;
|
287
|
+
|
288
|
+
mpf_make_struct_init (res_val, res, mpfr_get_default_prec());
|
289
|
+
mpfr_set_nan (res);
|
290
|
+
|
291
|
+
return res_val;
|
292
|
+
}
|
293
|
+
|
294
|
+
/*
|
295
|
+
* call-seq:
|
296
|
+
* GMP::F.inf
|
297
|
+
* GMP::F.inf(sign)
|
298
|
+
*
|
299
|
+
* Inf (positive infinity), an instance of GMP::F, or -Inf (negative infinity),
|
300
|
+
* if a negative Fixnum _sign_ is passed
|
301
|
+
*/
|
302
|
+
VALUE r_gmpfsg_inf(int argc, VALUE *argv, VALUE klass)
|
303
|
+
{
|
304
|
+
MP_FLOAT *res;
|
305
|
+
VALUE sign_val, res_val;
|
306
|
+
int sign;
|
307
|
+
(void)klass;
|
308
|
+
|
309
|
+
rb_scan_args (argc, argv, "01", &sign_val);
|
310
|
+
|
311
|
+
if (NIL_P (sign_val)) { sign = 1; }
|
312
|
+
else if (FIXNUM_P (sign_val)) { sign = FIX2INT (sign_val); }
|
313
|
+
else { typeerror_as (X, "sign"); }
|
314
|
+
mpf_make_struct_init (res_val, res, mpfr_get_default_prec());
|
315
|
+
mpfr_set_inf (res, sign);
|
316
|
+
|
317
|
+
return res_val;
|
318
|
+
}
|
319
|
+
|
320
|
+
#if MPFR_VERSION_MAJOR > 2
|
321
|
+
/*
|
322
|
+
* call-seq:
|
323
|
+
* GMP::F.zero
|
324
|
+
* GMP::F.zero(sign)
|
325
|
+
*
|
326
|
+
* zero or negative zero, an instance of GMP::F, depending on _sign_, a Fixnum
|
327
|
+
*/
|
328
|
+
VALUE r_gmpfsg_zero(int argc, VALUE *argv, VALUE klass)
|
329
|
+
{
|
330
|
+
MP_FLOAT *res;
|
331
|
+
VALUE sign_val, res_val;
|
332
|
+
int sign;
|
333
|
+
(void)klass;
|
334
|
+
|
335
|
+
rb_scan_args (argc, argv, "01", &sign_val);
|
336
|
+
|
337
|
+
if (NIL_P (sign_val)) { sign = 1; }
|
338
|
+
else if (FIXNUM_P (sign_val)) { sign = FIX2INT (sign_val); }
|
339
|
+
else { typeerror_as (X, "sign"); }
|
340
|
+
mpf_make_struct_init (res_val, res, mpfr_get_default_prec());
|
341
|
+
mpfr_set_zero (res, sign);
|
342
|
+
|
343
|
+
return res_val;
|
344
|
+
}
|
345
|
+
#endif /* MPFR_VERSION_MAJOR > 2 */
|
346
|
+
#endif /* MPFR */
|
226
347
|
|
227
348
|
/*
|
228
349
|
* call-seq:
|
@@ -255,86 +376,62 @@ VALUE r_gmpf_to_d(VALUE self)
|
|
255
376
|
return rb_float_new(mpf_get_d(self_val));
|
256
377
|
}
|
257
378
|
|
258
|
-
#ifdef MPFR
|
259
379
|
/*
|
260
380
|
* call-seq:
|
261
|
-
* x.to_s
|
381
|
+
* x.to_s(base = 10)
|
262
382
|
*
|
263
|
-
* Returns
|
383
|
+
* Returns a representation of _x_, as a String. By default, the String will be
|
384
|
+
* the decimal representation. Any valid GMP base can be passed.
|
264
385
|
*/
|
265
|
-
VALUE r_gmpf_to_s(int argc, VALUE *argv, VALUE
|
386
|
+
VALUE r_gmpf_to_s(int argc, VALUE *argv, VALUE self_val)
|
266
387
|
{
|
267
|
-
MP_FLOAT *
|
388
|
+
MP_FLOAT *self;
|
268
389
|
char *str, *str2;
|
269
|
-
VALUE
|
390
|
+
VALUE res_val;
|
270
391
|
mp_exp_t exponent;
|
271
392
|
VALUE base_val;
|
272
393
|
int base = 10;
|
273
394
|
|
274
|
-
mpf_get_struct(
|
395
|
+
mpf_get_struct (self_val, self);
|
275
396
|
|
276
397
|
/* TODO: accept a second optional argument, n_digits */
|
277
|
-
rb_scan_args(argc, argv, "01", &base_val);
|
278
|
-
if (NIL_P(base_val)) { base = 10; } /* default value */
|
279
|
-
else { base = get_base(base_val); }
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
398
|
+
rb_scan_args (argc, argv, "01", &base_val);
|
399
|
+
if (NIL_P (base_val)) { base = 10; } /* default value */
|
400
|
+
else { base = get_base (base_val); }
|
401
|
+
|
402
|
+
#ifndef MPFR
|
403
|
+
str = mpf_get_str (NULL, &exponent, base, 0, self);
|
404
|
+
#else
|
405
|
+
str = mpfr_get_str (NULL, &exponent, base, 0, self, __gmp_default_rounding_mode);
|
406
|
+
#endif
|
407
|
+
if ((strcmp (str, "NaN") == 0) ||
|
408
|
+
(strcmp (str, "Inf") == 0) ||
|
409
|
+
(strcmp (str, "-Inf") == 0))
|
285
410
|
{
|
286
|
-
|
411
|
+
res_val = rb_str_new2 (str);
|
287
412
|
}
|
288
413
|
else
|
289
414
|
{
|
290
415
|
if (str[0] == '-')
|
291
|
-
__gmp_asprintf(&str2, "-0.%se%+ld", str+1, exponent);
|
416
|
+
__gmp_asprintf (&str2, "-0.%se%+ld", str+1, exponent);
|
292
417
|
else
|
293
|
-
__gmp_asprintf(&str2, "0.%se%+ld", str, exponent);
|
418
|
+
__gmp_asprintf (&str2, "0.%se%+ld", str, exponent);
|
294
419
|
|
295
|
-
|
296
|
-
|
420
|
+
res_val = rb_str_new2 (str2);
|
421
|
+
#ifndef MPFR
|
422
|
+
free (str2);
|
423
|
+
#else
|
424
|
+
mpfr_free_str (str2);
|
425
|
+
#endif
|
297
426
|
}
|
298
427
|
|
299
|
-
|
300
|
-
|
301
|
-
}
|
428
|
+
#ifndef MPFR
|
429
|
+
free (str);
|
302
430
|
#else
|
303
|
-
|
304
|
-
* call-seq:
|
305
|
-
* x.to_s
|
306
|
-
*
|
307
|
-
* Returns the decimal representation of _x_, as a string.
|
308
|
-
*/
|
309
|
-
VALUE r_gmpf_to_s(VALUE self)
|
310
|
-
{
|
311
|
-
MP_FLOAT *self_val;
|
312
|
-
char *str, *str2;
|
313
|
-
VALUE res;
|
314
|
-
mp_exp_t exponent;
|
315
|
-
|
316
|
-
mpf_get_struct(self, self_val);
|
317
|
-
|
318
|
-
str = mpf_get_str(NULL, &exponent, 10, 0, self_val);
|
319
|
-
if ((strcmp(str, "NaN") == 0) ||
|
320
|
-
(strcmp(str, "Inf") == 0) ||
|
321
|
-
(strcmp(str, "-Inf") == 0))
|
322
|
-
{
|
323
|
-
res = rb_str_new2(str);
|
324
|
-
}
|
325
|
-
else
|
326
|
-
{
|
327
|
-
if (str[0] == '-')
|
328
|
-
__gmp_asprintf(&str2, "-0.%se%+ld", str+1, exponent);
|
329
|
-
else
|
330
|
-
__gmp_asprintf(&str2, "0.%se%+ld", str, exponent);
|
331
|
-
res = rb_str_new2(str2);
|
332
|
-
free(str2);
|
333
|
-
}
|
334
|
-
free(str);
|
335
|
-
return res;
|
336
|
-
}
|
431
|
+
mpfr_free_str (str);
|
337
432
|
#endif
|
433
|
+
return res_val;
|
434
|
+
}
|
338
435
|
|
339
436
|
|
340
437
|
/**********************************************************************
|
@@ -777,7 +874,11 @@ int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
|
|
777
874
|
return r_mpf_cmp (self_val, arg_val);
|
778
875
|
} else {
|
779
876
|
mpf_temp_init(arg_val, mpf_get_prec (self_val));
|
877
|
+
#ifndef MPFR
|
780
878
|
mpf_set_value (arg_val, arg);
|
879
|
+
#else
|
880
|
+
mpfr_set_value (arg_val, arg, __gmp_default_rounding_mode);
|
881
|
+
#endif
|
781
882
|
result = r_mpf_cmp (self_val, arg_val);
|
782
883
|
mpf_temp_free(arg_val);
|
783
884
|
return result;
|
@@ -786,7 +887,7 @@ int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
|
|
786
887
|
|
787
888
|
/*
|
788
889
|
* what does really "equal" mean ? it's not obvious
|
789
|
-
* Is this a note that I,
|
890
|
+
* Is this a note that I, srawlins, put in here? It is not obvious to me...
|
790
891
|
*/
|
791
892
|
VALUE r_gmpf_eq(VALUE self, VALUE arg)
|
792
893
|
{
|
@@ -827,6 +928,46 @@ VALUE r_gmpf_sgn(VALUE self)
|
|
827
928
|
return INT2FIX (mpf_sgn (self_val));
|
828
929
|
}
|
829
930
|
|
931
|
+
#ifdef MPFR
|
932
|
+
|
933
|
+
/*
|
934
|
+
* call-seq:
|
935
|
+
* x.lessgreater?(y)
|
936
|
+
*
|
937
|
+
* Return true if _x_ < _y_ or _x_ > _y_; false otherwise
|
938
|
+
*/
|
939
|
+
VALUE r_gmpfr_lessgreater_p(VALUE self_val, VALUE arg_val)
|
940
|
+
{
|
941
|
+
MP_FLOAT *self, *arg;
|
942
|
+
|
943
|
+
if (!GMPF_P (arg_val))
|
944
|
+
typeerror_as (F, "arg");
|
945
|
+
|
946
|
+
mpf_get_struct (self_val, self);
|
947
|
+
mpf_get_struct (arg_val, arg);
|
948
|
+
return (mpfr_lessgreater_p (self, arg) != 0) ? Qtrue : Qfalse;
|
949
|
+
}
|
950
|
+
|
951
|
+
/*
|
952
|
+
* call-seq:
|
953
|
+
* x.unordered?(y)
|
954
|
+
*
|
955
|
+
* Return true if _x_ or _y_ is a NaN; false otherwise
|
956
|
+
*/
|
957
|
+
VALUE r_gmpfr_unordered_p(VALUE self_val, VALUE arg_val)
|
958
|
+
{
|
959
|
+
MP_FLOAT *self, *arg;
|
960
|
+
|
961
|
+
if (!GMPF_P (arg_val))
|
962
|
+
typeerror_as (F, "arg");
|
963
|
+
|
964
|
+
mpf_get_struct (self_val, self);
|
965
|
+
mpf_get_struct (arg_val, arg);
|
966
|
+
return (mpfr_unordered_p (self, arg) != 0) ? Qtrue : Qfalse;
|
967
|
+
}
|
968
|
+
|
969
|
+
#endif /* MPFR */
|
970
|
+
|
830
971
|
|
831
972
|
/**********************************************************************
|
832
973
|
* Miscellaneous Float Functions *
|
@@ -853,6 +994,7 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
|
853
994
|
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
854
995
|
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
855
996
|
if (NIL_P (res_prec)) { res_prec_value = prec; } \
|
997
|
+
/* TODO test type */ \
|
856
998
|
else { res_prec_value = FIX2INT (res_prec); } \
|
857
999
|
mpf_make_struct_init (res, res_val, res_prec_value); \
|
858
1000
|
mpfr_##name (res_val, self_val, rnd_mode_val); \
|
@@ -874,8 +1016,10 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
|
874
1016
|
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
875
1017
|
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
876
1018
|
if (NIL_P (sin_prec)) { sin_prec_val = prec; } \
|
1019
|
+
/* TODO test type */ \
|
877
1020
|
else { sin_prec_val = FIX2INT (sin_prec); } \
|
878
1021
|
if (NIL_P (cos_prec)) { cos_prec_val = sin_prec_val; } \
|
1022
|
+
/* TODO test type */ \
|
879
1023
|
else { cos_prec_val = FIX2INT (cos_prec); } \
|
880
1024
|
mpf_make_struct_init (sinn, sin_val, sin_prec_val); \
|
881
1025
|
mpf_make_struct_init (coss, cos_val, cos_prec_val); \
|
@@ -922,6 +1066,7 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
|
922
1066
|
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
923
1067
|
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
924
1068
|
if (NIL_P (res_prec)) { res_prec_value = prec; } \
|
1069
|
+
/* TODO test type */ \
|
925
1070
|
else { res_prec_value = FIX2INT (res_prec); } \
|
926
1071
|
mpf_make_struct_init (res, res_val, res_prec_value); \
|
927
1072
|
mpfr_##name (res_val, arg1_val, self_val, rnd_mode_val); \
|
@@ -934,7 +1079,7 @@ static VALUE r_gmpfr_##name(VALUE self) \
|
|
934
1079
|
{ \
|
935
1080
|
MP_FLOAT *self_val; \
|
936
1081
|
\
|
937
|
-
mpf_get_struct(self, self_val);
|
1082
|
+
mpf_get_struct (self, self_val); \
|
938
1083
|
if (mpfr_##name (self_val)) \
|
939
1084
|
return Qtrue; \
|
940
1085
|
else \
|
@@ -955,15 +1100,48 @@ VALUE r_gmpfrsg_##name(int argc, VALUE *argv, VALUE self) \
|
|
955
1100
|
rb_scan_args (argc, argv, "02", &rnd_mode, &prec); \
|
956
1101
|
\
|
957
1102
|
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
958
|
-
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); }
|
1103
|
+
else { rnd_mode_val = r_get_rounding_mode (rnd_mode); } \
|
959
1104
|
if (NIL_P (prec)) { prec_val = mpfr_get_default_prec(); } \
|
960
|
-
else { prec_val = FIX2INT (prec); }
|
1105
|
+
else if (FIXNUM_P (prec)) { prec_val = FIX2INT (prec); } \
|
1106
|
+
else { typeerror_as (Z, "prec"); } \
|
961
1107
|
mpf_make_struct_init (res, res_val, prec_val); \
|
962
1108
|
mpfr_##name (res_val, rnd_mode_val); \
|
963
1109
|
\
|
964
1110
|
return res; \
|
965
1111
|
}
|
966
1112
|
|
1113
|
+
/*
|
1114
|
+
* call-seq:
|
1115
|
+
* exp, y = x.frexp(rnd_mode = nil, prec = nil)
|
1116
|
+
*
|
1117
|
+
* Set _exp_ and _y_ such that
|
1118
|
+
* 0.5 <= _abs(y)_ < 1 and _y_ times 2 raised to _exp_ equals _x_ rounded to _prec_, or the precision
|
1119
|
+
* of _x_, using the given rounding mode. If _x_ is zero, then _y_ is set to a zero
|
1120
|
+
* of the same sign and _exp_ is set to 0. If _x_ is NaN or an infinity, then _y_ is
|
1121
|
+
* set to the same value and _exp_ is undefined.
|
1122
|
+
*/
|
1123
|
+
VALUE r_gmpfr_frexp(int argc, VALUE *argv, VALUE self_val)
|
1124
|
+
{
|
1125
|
+
MP_FLOAT *self, *res;
|
1126
|
+
VALUE rnd_mode_val, res_prec_val, exp_val, res_val;
|
1127
|
+
mpfr_prec_t prec, res_prec;
|
1128
|
+
mp_rnd_t rnd_mode;
|
1129
|
+
mpfr_exp_t exp;
|
1130
|
+
|
1131
|
+
mpf_get_struct_prec (self_val, self, prec);
|
1132
|
+
|
1133
|
+
rb_scan_args (argc, argv, "02", &rnd_mode_val, &res_prec_val);
|
1134
|
+
if (NIL_P (rnd_mode_val)) { rnd_mode = __gmp_default_rounding_mode; }
|
1135
|
+
else { rnd_mode = r_get_rounding_mode (rnd_mode_val); }
|
1136
|
+
if (NIL_P (res_prec_val)) { res_prec = prec; }
|
1137
|
+
else { res_prec = FIX2INT (res_prec_val); }
|
1138
|
+
mpf_make_struct_init (res_val, res, res_prec);
|
1139
|
+
mpfr_frexp (&exp, res, self, rnd_mode);
|
1140
|
+
exp_val = INT2FIX (exp);
|
1141
|
+
|
1142
|
+
return rb_assoc_new(exp_val, res_val);
|
1143
|
+
}
|
1144
|
+
|
967
1145
|
MPFR_SINGLE_FUNCTION(sqrt)
|
968
1146
|
MPFR_SINGLE_FUNCTION(rec_sqrt)
|
969
1147
|
MPFR_SINGLE_FUNCTION(cbrt)
|
@@ -1019,6 +1197,41 @@ MPFR_SINGLE_LONG_FUNCTION(yn)
|
|
1019
1197
|
MPFR_SINGLE_MPF_FUNCTION(agm)
|
1020
1198
|
MPFR_SINGLE_MPF_FUNCTION(hypot)
|
1021
1199
|
|
1200
|
+
/*
|
1201
|
+
* call-seq:
|
1202
|
+
* GMP::F.fac(n)
|
1203
|
+
* GMP::F.fac(n, rounding_mode)
|
1204
|
+
* GMP::F.fac(n, rounding_mode, precision)
|
1205
|
+
*
|
1206
|
+
* Creates a new GMP::F float, equal to the factorial of n, which must be a
|
1207
|
+
* Fixnum. Optionally pass a rounding mode, and precision for the resultant
|
1208
|
+
* GMP::F.
|
1209
|
+
*/
|
1210
|
+
VALUE r_gmpfrsg_fac(int argc, VALUE *argv, VALUE self_val)
|
1211
|
+
{
|
1212
|
+
MP_FLOAT *res;
|
1213
|
+
VALUE arg_val, res_val;
|
1214
|
+
VALUE rnd_mode_val, prec_val;
|
1215
|
+
mp_rnd_t rnd_mode;
|
1216
|
+
mpfr_prec_t prec;
|
1217
|
+
unsigned long int arg;
|
1218
|
+
(void)self_val;
|
1219
|
+
|
1220
|
+
rb_scan_args (argc, argv, "12", &arg_val, &rnd_mode_val, &prec_val);
|
1221
|
+
|
1222
|
+
if (FIXNUM_P (arg_val)) { arg = FIX2INT (arg_val); }
|
1223
|
+
else { rb_raise (rb_eTypeError, "operand must be a Fixnum"); }
|
1224
|
+
if (NIL_P (rnd_mode_val)) { rnd_mode = __gmp_default_rounding_mode; }
|
1225
|
+
else { rnd_mode = r_get_rounding_mode (rnd_mode_val); }
|
1226
|
+
if (NIL_P (prec_val)) { prec = mpfr_get_default_prec(); }
|
1227
|
+
/* TODO check type */
|
1228
|
+
else { prec = FIX2INT (prec_val); }
|
1229
|
+
mpf_make_struct_init (res_val, res, prec);
|
1230
|
+
mpfr_fac_ui (res, arg, rnd_mode);
|
1231
|
+
|
1232
|
+
return res_val;
|
1233
|
+
}
|
1234
|
+
|
1022
1235
|
//VALUE r_gmpfrsg_sprintf(int argc, VALUE *argv, VALUE self)
|
1023
1236
|
//rb_scan_args (argc, argv, "1*", &format, &list);
|
1024
1237
|
VALUE r_gmpfrsg_sprintf2(VALUE klass, VALUE format, VALUE arg) {
|
@@ -1028,17 +1241,17 @@ VALUE r_gmpfrsg_sprintf2(VALUE klass, VALUE format, VALUE arg) {
|
|
1028
1241
|
MP_INT *arg_val_z;
|
1029
1242
|
MP_FLOAT *arg_val_f;
|
1030
1243
|
(void)klass;
|
1031
|
-
format_str = StringValuePtr(format);
|
1032
|
-
if (GMPZ_P(arg)) {
|
1244
|
+
format_str = StringValuePtr (format);
|
1245
|
+
if (GMPZ_P (arg)) {
|
1033
1246
|
mpz_get_struct (arg, arg_val_z);
|
1034
|
-
mpfr_asprintf(&buffer, format_str, arg_val_z);
|
1035
|
-
} else if (GMPF_P(arg)) {
|
1247
|
+
mpfr_asprintf (&buffer, format_str, arg_val_z);
|
1248
|
+
} else if (GMPF_P (arg)) {
|
1036
1249
|
mpf_get_struct (arg, arg_val_f);
|
1037
|
-
mpfr_asprintf(&buffer, format_str, arg_val_f);
|
1250
|
+
mpfr_asprintf (&buffer, format_str, arg_val_f);
|
1038
1251
|
}
|
1039
1252
|
|
1040
|
-
res = rb_str_new2(buffer);
|
1041
|
-
free(buffer);
|
1253
|
+
res = rb_str_new2 (buffer);
|
1254
|
+
free (buffer);
|
1042
1255
|
return res;
|
1043
1256
|
}
|
1044
1257
|
|
@@ -1248,6 +1461,13 @@ void init_gmpf()
|
|
1248
1461
|
// Initializing, Assigning Floats
|
1249
1462
|
rb_define_singleton_method(cGMP_F, "new", r_gmpfsg_new, -1);
|
1250
1463
|
rb_define_method(cGMP_F, "initialize", r_gmpf_initialize, -1);
|
1464
|
+
#ifdef MPFR
|
1465
|
+
rb_define_singleton_method(cGMP_F, "nan", r_gmpfsg_nan, 0);
|
1466
|
+
rb_define_singleton_method(cGMP_F, "inf", r_gmpfsg_inf, -1);
|
1467
|
+
#if MPFR_VERSION_MAJOR>2
|
1468
|
+
rb_define_singleton_method(cGMP_F, "zero", r_gmpfsg_zero, -1);
|
1469
|
+
#endif /* MPFR_VERSION_MAJOR>2 */
|
1470
|
+
#endif /* MPFR */
|
1251
1471
|
rb_define_method(cGMP_F, "prec", r_gmpf_get_prec, 0);
|
1252
1472
|
rb_define_method(cGMP_F, "prec=", r_gmpf_set_prec, 1);
|
1253
1473
|
rb_define_method(cGMP_F, "prec_raw=", r_gmpf_set_prec_raw, 1);
|
@@ -1296,17 +1516,13 @@ void init_gmpf()
|
|
1296
1516
|
|
1297
1517
|
|
1298
1518
|
#ifdef MPFR
|
1299
|
-
/*
|
1519
|
+
/* TODO: new in MPFR 3.0.0:
|
1300
1520
|
*
|
1301
|
-
* mpfr_set_zero
|
1302
1521
|
* mpfr_ai
|
1303
|
-
* mpfr_set_flt
|
1304
|
-
* mpfr_get_flt
|
1305
|
-
* mpfr_urandom
|
1306
1522
|
* mpfr_set_z_2exp
|
1307
1523
|
*/
|
1308
1524
|
|
1309
|
-
/*
|
1525
|
+
/* TODO: new in MPFR 3.1.0:
|
1310
1526
|
*
|
1311
1527
|
* mpfr_buildopt_gmpinternals_p
|
1312
1528
|
* mpfr_buildopt_tune_case
|
@@ -1314,19 +1530,18 @@ void init_gmpf()
|
|
1314
1530
|
* mpfr_grandom
|
1315
1531
|
* mpfr_z_sub
|
1316
1532
|
*/
|
1533
|
+
#if MPFR_VERSION_MAJOR >= 3 && MPFR_VERSION_MINOR >= 1
|
1534
|
+
rb_define_method(cGMP_F, "frexp", r_gmpfr_frexp, -1);
|
1535
|
+
#endif /* MPFR_VERSION >= 3.1 */
|
1317
1536
|
|
1318
1537
|
// Basic Arithmetic Functions
|
1319
1538
|
rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, -1);
|
1320
1539
|
rb_define_method(cGMP_F, "rec_sqrt", r_gmpfr_rec_sqrt, -1);
|
1321
1540
|
rb_define_method(cGMP_F, "cbrt", r_gmpfr_cbrt, -1);
|
1322
|
-
// "root", r_gmpfr_root
|
1323
|
-
// "
|
1324
|
-
// "
|
1325
|
-
// "
|
1326
|
-
// "mul_2", r_gmpfr_mul_2
|
1327
|
-
// "div_2", r_gmpfr_div_2
|
1328
|
-
|
1329
|
-
//rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
|
1541
|
+
// TODO "root", r_gmpfr_root
|
1542
|
+
// TODO "dim", r_gmpfr_dim
|
1543
|
+
// TODO "mul_2", r_gmpfr_mul_2
|
1544
|
+
// TODO "div_2", r_gmpfr_div_2
|
1330
1545
|
|
1331
1546
|
// Comparison Functions
|
1332
1547
|
rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
|
@@ -1337,9 +1552,8 @@ void init_gmpf()
|
|
1337
1552
|
#if MPFR_VERSION_MAJOR > 2
|
1338
1553
|
rb_define_method(cGMP_F, "regular?", r_gmpfr_regular_p, 0);
|
1339
1554
|
#endif
|
1340
|
-
|
1341
|
-
|
1342
|
-
//"unordered", r_gmpfr_unordered_p
|
1555
|
+
rb_define_method(cGMP_F, "lessgreater?", r_gmpfr_lessgreater_p, 1);
|
1556
|
+
rb_define_method(cGMP_F, "unordered?", r_gmpfr_unordered_p, 1);
|
1343
1557
|
|
1344
1558
|
// Special Functions
|
1345
1559
|
rb_define_method(cGMP_F, "log", r_gmpfr_log, -1);
|
@@ -1370,7 +1584,7 @@ void init_gmpf()
|
|
1370
1584
|
rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, -1);
|
1371
1585
|
rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, -1);
|
1372
1586
|
|
1373
|
-
|
1587
|
+
rb_define_singleton_method(cGMP_F, "fac", r_gmpfrsg_fac, -1);
|
1374
1588
|
|
1375
1589
|
rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, -1);
|
1376
1590
|
rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, -1);
|
@@ -1378,7 +1592,7 @@ void init_gmpf()
|
|
1378
1592
|
rb_define_method(cGMP_F, "li2", r_gmpfr_li2, -1);
|
1379
1593
|
rb_define_method(cGMP_F, "gamma", r_gmpfr_gamma, -1);
|
1380
1594
|
rb_define_method(cGMP_F, "lngamma", r_gmpfr_lngamma, -1);
|
1381
|
-
/*rb_define_method(cGMP_F, "lgamma", r_gmpfr_lgamma, -1)
|
1595
|
+
/* TODO rb_define_method(cGMP_F, "lgamma", r_gmpfr_lgamma, -1); */
|
1382
1596
|
#if MPFR_VERSION_MAJOR > 2
|
1383
1597
|
rb_define_method(cGMP_F, "digamma", r_gmpfr_digamma, -1);
|
1384
1598
|
#endif
|
@@ -1392,11 +1606,11 @@ void init_gmpf()
|
|
1392
1606
|
rb_define_method(cGMP_F, "y1", r_gmpfr_y1, -1);
|
1393
1607
|
rb_define_method(cGMP_F, "yn", r_gmpfr_yn, -1);
|
1394
1608
|
|
1395
|
-
|
1396
|
-
|
1609
|
+
/* TODO "fma", r_gmpfr_fma */
|
1610
|
+
/* TODO "fms", r_gmpfr_fms */
|
1397
1611
|
rb_define_method(cGMP_F, "agm", r_gmpfr_agm, -1);
|
1398
1612
|
rb_define_method(cGMP_F, "hypot", r_gmpfr_hypot, -1);
|
1399
|
-
|
1613
|
+
/* TODO "ai", r_gmpfr_ai !! 3.0.0 */
|
1400
1614
|
|
1401
1615
|
// Formatted Output Functions
|
1402
1616
|
rb_define_singleton_method(cGMP_F, "sprintf2", r_gmpfrsg_sprintf2, 2);
|
@@ -1407,7 +1621,6 @@ void init_gmpf()
|
|
1407
1621
|
rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan, -1);
|
1408
1622
|
|
1409
1623
|
// Integer and Remainder Related Functions
|
1410
|
-
// "integer?", r_gmpfr_integer_p
|
1411
1624
|
rb_define_method(cGMP_F, "integer?", r_gmpfr_integer_p, 0);
|
1412
1625
|
|
1413
1626
|
// Rounding Related Functions
|
@@ -1421,6 +1634,4 @@ void init_gmpf()
|
|
1421
1634
|
rb_define_singleton_method (cGMP_F, "mpfr_buildopt_tls_p", r_gmpfsg_mpfr_buildopt_tls_p, 0);
|
1422
1635
|
#endif /* MPFR > 2 */
|
1423
1636
|
#endif /* MPFR */
|
1424
|
-
|
1425
|
-
// _unsorted_
|
1426
1637
|
}
|