gmp 0.6.47 → 0.7.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +21 -1
- data/README.markdown +29 -9
- data/ext/extconf.rb +8 -0
- data/ext/gmp.c +7 -7
- data/ext/gmpf.c +620 -139
- data/ext/gmpq.c +218 -90
- data/ext/gmprandstate.c +57 -53
- data/ext/gmpz.c +492 -440
- data/ext/mprnd.c +44 -35
- data/ext/ruby_gmp.h +6 -6
- data/manual.pdf +0 -0
- data/manual.tex +2 -2
- data/test/mpfr_thypot.rb +60 -0
- data/test/tc_cmp.rb +1 -1
- data/test/tc_constants.rb +1 -1
- data/test/tc_division.rb +1 -1
- data/test/tc_f_abs_neg.rb +1 -1
- data/test/tc_f_arithmetics_coersion.rb +1 -1
- data/test/tc_f_precision.rb +2 -1
- data/test/tc_f_to_s.rb +1 -1
- data/test/tc_hashes.rb +1 -4
- data/test/tc_mpfr_cmp.rb +1 -1
- data/test/tc_mpfr_constants.rb +1 -1
- data/test/tc_mpfr_functions.rb +43 -10
- data/test/tc_mpfr_inf_nan_zero.rb +1 -1
- data/test/tc_mpfr_integer.rb +1 -1
- data/test/tc_mpfr_new_rounding.rb +24 -1
- data/test/tc_mpfr_pow.rb +17 -0
- data/test/tc_mpfr_random.rb +1 -1
- data/test/tc_mpfr_rounding.rb +1 -1
- data/test/tc_q.rb +53 -32
- data/test/tc_q_basic.rb +1 -1
- data/test/{tc_floor_ceil_truncate.rb → tc_q_floor_ceil_truncate.rb} +2 -2
- data/test/tc_q_num_den.rb +18 -0
- data/test/tc_random.rb +1 -4
- data/test/tc_sgn_neg_abs.rb +1 -1
- data/test/tc_swap.rb +1 -1
- data/test/tc_z.rb +1 -1
- data/test/tc_z_addmul.rb +1 -1
- data/test/tc_z_basic.rb +3 -2
- data/test/tc_z_exponentiation.rb +5 -5
- data/test/tc_z_export_import.rb +1 -1
- data/test/{tc_fib_fac_nextprime.rb → tc_z_fib_fac_nextprime.rb} +1 -1
- data/test/tc_z_functional_mappings.rb +2 -2
- data/test/tc_z_gcd_lcm_invert.rb +1 -1
- data/test/tc_z_hamdist.rb +1 -1
- data/test/tc_z_io.rb +2 -1
- data/test/tc_z_jac_leg_rem.rb +1 -1
- data/test/tc_z_logic.rb +1 -1
- data/test/{tc_logical_roots.rb → tc_z_logical_roots.rb} +7 -7
- data/test/tc_z_shifts_last_bits.rb +2 -2
- data/test/tc_z_submul.rb +1 -1
- data/test/tc_z_to_dis.rb +1 -1
- data/test/{tc_zerodivisionexceptions.rb → tc_zero_division_exceptions.rb} +2 -2
- data/test/unit_tests.rb +30 -17
- metadata +16 -16
- data/INSTALL +0 -4
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a40972b493a89ea10856fa799609c7dccea84d13
|
4
|
+
data.tar.gz: 1614d5eb7cf7846add652665a32d1a92035b3843
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d6500aca0dec138a7a83a6e4f6e483b5cc7b532aca8f02cf397f4f04eda9ffda3f08342d3e69ea62f94ff33a637062d6837736a3259a0103ef00047c198d83e8
|
7
|
+
data.tar.gz: 03d62dc2d10bd81a380b0413c168c4db1056564c6e2e5a573cf74fea14e3354f552884647222cf298f23f5ba77e646bfa4c0d358c5733f75daa51bec5582f444
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
0.7.19
|
2
|
+
* GMP::Q.new can now accept a GMP::Z or Fixnum more intelligently, and can
|
3
|
+
accept a Float, and is tested better.
|
4
|
+
* GMP::F.new can now accept a rounding mode after the base, when a String is
|
5
|
+
passed in.
|
6
|
+
* Rakefile is much more robust with various dependencies.
|
7
|
+
* Yardoc documentation is less completely broken.
|
8
|
+
* GMP::F#** is now slightly more efficient when the argument is a Fixnum or
|
9
|
+
GMP::Z, and is now tested.
|
10
|
+
* Bigger error message when GMP can't be found. Fixes #4.
|
11
|
+
* Rearrange args for GMP::F#atan2, #agm, and #hypot; contributed by @timpeters
|
12
|
+
* Allow Float for args to GMP::F#atan2, #agm, and #hypot; contributed by
|
13
|
+
@timpeters
|
14
|
+
* Sanity checks for GMP::F#hypot
|
15
|
+
* Added new MPFR class methods: GMP::F.emin, GMP::F.emax, GMP::F.emin=,
|
16
|
+
GMP::F.emax=, GMP::F.emin_min, GMP::F.emin_max, GMP::F.emax_min, and
|
17
|
+
GMP::F.emax_max; also minimal tests, and documentation
|
18
|
+
* Added new MPFR constructor method: GMP::F.new_2exp, not really tested :)
|
19
|
+
|
1
20
|
0.6.47
|
2
21
|
* Fixed GMP::F#to_s when MPFR is not present. It now works, and accepts an
|
3
22
|
optional base argument, just like GMP::F#to_s does when MPFR _is_ present.
|
@@ -9,7 +28,8 @@
|
|
9
28
|
tests
|
10
29
|
* Added tests for GMP::F#abs and GMP::F#neg
|
11
30
|
* 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,
|
31
|
+
* Added GMP::F.nan, GMP::F.inf, GMP::F.zero (MPFR >= 3.0.0), documentation,
|
32
|
+
and simple tests
|
13
33
|
* Added GMP::F#frexp, documentation, and tests
|
14
34
|
* Fixed GMP::MPFR_RNDA
|
15
35
|
|
data/README.markdown
CHANGED
@@ -3,8 +3,9 @@ gmp
|
|
3
3
|
|
4
4
|
[![Build Status](https://travis-ci.org/srawlins/gmp.png?branch=master)](https://travis-ci.org/srawlins/gmp)
|
5
5
|
|
6
|
-
gmp is
|
7
|
-
|
6
|
+
gmp is a Rubygem providing Ruby bindings to the [GMP](https://gmplib.org/)
|
7
|
+
library, and to the [MPFR](http://www.mpfr.org/) library (optional). Here is the
|
8
|
+
introduction paragraph at [GMP's homepage](http://gmplib.org/#WHAT):
|
8
9
|
|
9
10
|
> GMP is a free library for arbitrary precision arithmetic, operating on
|
10
11
|
> signed integers, rational numbers, and floating point numbers. There is no
|
@@ -49,17 +50,20 @@ paragraph at [their homepage](http://gmplib.org/#WHAT):
|
|
49
50
|
> contributions, meaning users can safely use GMP. To achieve this, we will ask
|
50
51
|
> contributors to sign paperwork where they allow us to distribute their work."
|
51
52
|
|
52
|
-
|
53
|
-
2.1.0. GMP 5.1.x is the only version of GMP that has been tested recently.
|
54
|
-
Other Ruby platforms (such as Rubinius and JRuby) should be supported, but have not
|
55
|
-
been tested recently.
|
53
|
+
### Support
|
56
54
|
|
57
|
-
|
55
|
+
* GMP 4.3.x and GMP 5.x are each supported against Ruby (MRI) 1.9.x, 2.0.0, and
|
56
|
+
2.1.0. GMP 5.1.x is the only version of GMP that has been tested recently.
|
57
|
+
* MPFR 3.x is supported.
|
58
|
+
* Other Ruby platforms (such as Rubinius and JRuby) should be supported, but
|
59
|
+
have not been tested recently.
|
60
|
+
|
61
|
+
#### Previously
|
58
62
|
|
59
63
|
Previously, on version 0.5.47, this gem was verified as functioning in the
|
60
64
|
following combinations:
|
61
65
|
|
62
|
-
<table border="
|
66
|
+
<table border="0">
|
63
67
|
<tr>
|
64
68
|
<th>Platform</th>
|
65
69
|
<th>Ruby</th>
|
@@ -163,7 +167,7 @@ as pi, are defined under class methods of GMP::F, listed below.
|
|
163
167
|
* `GMP::GMP_BITS_PER_LIMB` The number of bits per limb
|
164
168
|
* `GMP::GMP_NUMB_MAX` - The maximum value that can be stored in the number part of a limb
|
165
169
|
|
166
|
-
|
170
|
+
If MPFR is available:
|
167
171
|
* `GMP::MPFR_VERSION` - A string like "2.4.2"
|
168
172
|
* `GMP::MPFR_PREC_MIN` - The minimum precision available
|
169
173
|
* `GMP::MPFR_PREC_MAX` - The maximum precision available
|
@@ -196,18 +200,26 @@ Numbers are created by using `new()`. Constructors can take following arguments:
|
|
196
200
|
GMP::Z.new(Bignum)
|
197
201
|
GMP::Z.new(String)
|
198
202
|
GMP::Q.new()
|
203
|
+
GMP::Q.new(Fixnum)
|
204
|
+
GMP::Q.new(GMP::Z)
|
199
205
|
GMP::Q.new(GMP::Q)
|
200
206
|
GMP::Q.new(String)
|
201
207
|
GMP::Q.new(any GMP::Z initializer)
|
208
|
+
GMP::Q.new(Fixnum, Fixnum)
|
202
209
|
GMP::Q.new(any GMP::Z initializer, any GMP::Z initializer)
|
203
210
|
GMP::F.new()
|
204
211
|
GMP::F.new(GMP::Z, precision=0, rounding_mode=default)
|
205
212
|
GMP::F.new(GMP::Q, precision=0, rounding_mode=default)
|
206
213
|
GMP::F.new(GMP::F, precision=0, rounding_mode=default)
|
207
214
|
GMP::F.new(String, precision=0)
|
215
|
+
GMP::F.new(String, precision=0, base=10)
|
216
|
+
GMP::F.new(String, precision=0, base=10, rounding_mode=default)
|
208
217
|
GMP::F.new(Fixnum, precision=0, rounding_mode=default)
|
209
218
|
GMP::F.new(Bignum, precision=0, rounding_mode=default)
|
210
219
|
GMP::F.new(Float, precision=0, roundung_mode=default)
|
220
|
+
GMP::F.new_2exp(Fixnum, exp, precision=0, rounding_mode=default)
|
221
|
+
GMP::F.new_2exp(Bignum, exp, precision=0, rounding_mode=default)
|
222
|
+
GMP::F.new_2exp(GMP::Z, exp, precision=0, rounding_mode=default)
|
211
223
|
GMP::RandState.new(\[algorithm\] \[, algorithm_args\])
|
212
224
|
|
213
225
|
You can also call them as:
|
@@ -337,6 +349,14 @@ Methods
|
|
337
349
|
const_pi returns pi
|
338
350
|
const_euler returns euler
|
339
351
|
const_catalan returns catalan
|
352
|
+
emin returns the smallest allowed exponent
|
353
|
+
emax returns the largest allowed exponent
|
354
|
+
emin=(exp) sets the smallest allowed exponent
|
355
|
+
emax=(exp) sets the largest allowed exponent
|
356
|
+
emin_min returns the smallest exponent allowed for GMP::F.emin=
|
357
|
+
emin_max returns the largest exponent allowed for GMP::F.emin=
|
358
|
+
emax_min returns the smallest exponent allowed for GMP::F.emax=
|
359
|
+
emax_max returns the largest exponent allowed for GMP::F.emax=
|
340
360
|
mpfr_buildopt_tls_p returns whether MPFR was built as thread safe
|
341
361
|
mpfr_buildopt_decimal_p returns whether MPFR was compiled with decimal
|
342
362
|
float support
|
data/ext/extconf.rb
CHANGED
@@ -43,6 +43,9 @@ if (begin; JRuby; rescue NameError; end) != nil
|
|
43
43
|
end
|
44
44
|
|
45
45
|
|
46
|
+
# This test is actually due to a Clang 3.3 shortcoming, included in OS X 10.9,
|
47
|
+
# fixed in Clang 3.4:
|
48
|
+
# http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html#new-compiler-flags
|
46
49
|
if try_compile('', '-O6')
|
47
50
|
$CFLAGS += ' -Wall -W -O6 -g'
|
48
51
|
else
|
@@ -52,6 +55,11 @@ end
|
|
52
55
|
if ok
|
53
56
|
create_makefile('gmp')
|
54
57
|
else
|
58
|
+
$stderr.puts "*********************************************************************"
|
59
|
+
$stderr.puts "Your compiler was unable to link to GMP while installing the gmp gem."
|
60
|
+
$stderr.puts "Please install GMP before installing the gmp gem."
|
61
|
+
$stderr.puts "*********************************************************************"
|
62
|
+
|
55
63
|
raise "Unable to build, correct above errors and rerun"
|
56
64
|
end
|
57
65
|
|
data/ext/gmp.c
CHANGED
@@ -49,11 +49,11 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
|
|
49
49
|
(void)klass;
|
50
50
|
if (FIXNUM_P(arg)) {
|
51
51
|
if (FIX2NUM(arg) <= 0) {
|
52
|
-
rb_raise(rb_eRangeError, "
|
52
|
+
rb_raise(rb_eRangeError, "precision must be positive");
|
53
53
|
}
|
54
54
|
mpf_set_default_prec (FIX2NUM(arg));
|
55
55
|
} else {
|
56
|
-
rb_raise(rb_eTypeError, "
|
56
|
+
rb_raise(rb_eTypeError, "precision must be Fixnum");
|
57
57
|
}
|
58
58
|
return Qnil;
|
59
59
|
}
|
@@ -84,6 +84,8 @@ int get_base(VALUE base_val) {
|
|
84
84
|
} else {
|
85
85
|
rb_raise(rb_eTypeError, "Expected Fixnum or one of :bin, :oct, :dec, :hex");
|
86
86
|
}
|
87
|
+
|
88
|
+
return 0; /* should never get here */
|
87
89
|
}
|
88
90
|
|
89
91
|
VALUE r_gmpsg_sprintf2(VALUE klass, VALUE format, VALUE arg) {
|
@@ -116,7 +118,7 @@ VALUE r_gmpsg_sprintf2(VALUE klass, VALUE format, VALUE arg) {
|
|
116
118
|
#ifdef MPFR
|
117
119
|
mp_rnd_t r_get_rounding_mode(VALUE rnd)
|
118
120
|
{
|
119
|
-
VALUE mode;
|
121
|
+
VALUE mode = 0;
|
120
122
|
int max_rnd;
|
121
123
|
|
122
124
|
#if MPFR_VERSION_MAJOR>2
|
@@ -126,12 +128,12 @@ mp_rnd_t r_get_rounding_mode(VALUE rnd)
|
|
126
128
|
#endif
|
127
129
|
|
128
130
|
if (GMPRND_P (rnd)) {
|
129
|
-
mode = rb_funcall (rnd, rb_intern("mode"), 0);
|
131
|
+
mode = rb_funcall (rnd, rb_intern ("mode"), 0);
|
130
132
|
if (FIX2INT (mode) < 0 || FIX2INT (mode) > max_rnd) {
|
131
133
|
rb_raise (rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
|
132
134
|
}
|
133
135
|
} else {
|
134
|
-
rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
136
|
+
rb_raise (rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
135
137
|
}
|
136
138
|
|
137
139
|
switch (FIX2INT (mode)) {
|
@@ -197,8 +199,6 @@ void Init_gmp() {
|
|
197
199
|
init_gmpq ();
|
198
200
|
rb_define_method(cGMP_Q, "initialize", r_gmpq_initialize, -1);
|
199
201
|
rb_define_method(cGMP_Q, "coerce", r_gmpq_coerce, 1);
|
200
|
-
rb_define_method(cGMP_Q, "num", r_gmpq_num, 0);
|
201
|
-
rb_define_method(cGMP_Q, "den", r_gmpq_den, 0);
|
202
202
|
|
203
203
|
cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
|
204
204
|
init_gmpf ();
|
data/ext/gmpf.c
CHANGED
@@ -7,8 +7,8 @@
|
|
7
7
|
*
|
8
8
|
* GMP Multiple Precision floating point numbers.
|
9
9
|
*
|
10
|
-
* Instances of this class can store variables of the type mpf_t
|
11
|
-
* also contains many methods that act as the functions for mpf_t variables,
|
10
|
+
* Instances of this class can store variables of the type `mpf_t`. This class
|
11
|
+
* also contains many methods that act as the functions for `mpf_t` variables,
|
12
12
|
* as well as a few methods that attempt to make this library more Ruby-ish.
|
13
13
|
*/
|
14
14
|
|
@@ -85,7 +85,7 @@ VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass)
|
|
85
85
|
(void)klass;
|
86
86
|
|
87
87
|
if (argc > 4)
|
88
|
-
rb_raise(rb_eArgError, "wrong
|
88
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0, 1, 2, 3, or 4)", argc);
|
89
89
|
|
90
90
|
mpf_make_struct (res, res_val);
|
91
91
|
rb_obj_call_init(res, argc, argv);
|
@@ -118,18 +118,18 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
118
118
|
|
119
119
|
arg = argv[0];
|
120
120
|
|
121
|
-
|
121
|
+
/* argc >= 2 ==> argv[0] is value, argv[1] is prec */
|
122
122
|
if (argc >= 2) {
|
123
123
|
if (FIXNUM_P(argv[1])) {
|
124
124
|
if (FIX2INT(argv[1]) >= 0)
|
125
125
|
prec = FIX2INT(argv[1]);
|
126
126
|
else {
|
127
127
|
r_mpf_init (self_val);
|
128
|
-
rb_raise(rb_eRangeError, "
|
128
|
+
rb_raise(rb_eRangeError, "precision must be non-negative");
|
129
129
|
}
|
130
130
|
} else {
|
131
131
|
r_mpf_init (self_val);
|
132
|
-
rb_raise(rb_eTypeError, "
|
132
|
+
rb_raise(rb_eTypeError, "precision must be a Fixnum");
|
133
133
|
}
|
134
134
|
} else if (GMPF_P(arg)) {
|
135
135
|
mpf_get_struct (arg, arg_val_f);
|
@@ -143,24 +143,24 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
143
143
|
else
|
144
144
|
mpfr_init2 (self_val, prec);
|
145
145
|
|
146
|
-
if (STRING_P(argv[0])) {
|
146
|
+
if (STRING_P (argv[0])) {
|
147
147
|
if (argc >= 3) {
|
148
|
-
if (FIXNUM_P(argv[2]))
|
149
|
-
if (FIX2INT(argv[2]) >= 2 && FIX2INT(argv[2]) <= 36)
|
150
|
-
base = FIX2INT(argv[2]);
|
151
|
-
else
|
152
|
-
rb_raise(rb_eRangeError, "base must be between 2 and 36");
|
153
|
-
}
|
154
|
-
else {
|
148
|
+
if (! FIXNUM_P (argv[2]))
|
155
149
|
rb_raise(rb_eTypeError, "base must be a Fixnum");
|
156
|
-
}
|
157
|
-
}
|
158
150
|
|
159
|
-
|
160
|
-
|
151
|
+
if (FIX2INT (argv[2]) >= 2 && FIX2INT (argv[2]) <= 36)
|
152
|
+
base = FIX2INT (argv[2]);
|
153
|
+
else
|
154
|
+
rb_raise (rb_eRangeError, "base must be between 2 and 36");
|
155
|
+
|
156
|
+
if (argc == 4)
|
157
|
+
rnd_mode_val = r_get_rounding_mode (argv[3]);
|
158
|
+
else
|
159
|
+
rnd_mode_val = __gmp_default_rounding_mode;
|
161
160
|
}
|
162
161
|
|
163
|
-
|
162
|
+
|
163
|
+
mpf_set_value2 (self_val, arg, base, rnd_mode_val);
|
164
164
|
return Qnil;
|
165
165
|
} else { /* not STRING_P(argv[0]) */
|
166
166
|
if (argc == 3)
|
@@ -188,7 +188,7 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
188
188
|
} else {
|
189
189
|
mpf_set_value (self_val, arg);
|
190
190
|
}
|
191
|
-
#endif
|
191
|
+
#endif /* MPFR */
|
192
192
|
|
193
193
|
return Qnil;
|
194
194
|
}
|
@@ -261,23 +261,81 @@ void mpfr_set_value(MP_FLOAT *self_val, VALUE arg, mp_rnd_t rnd_mode_val)
|
|
261
261
|
}
|
262
262
|
}
|
263
263
|
|
264
|
-
void mpf_set_value2(MP_FLOAT *self_val, VALUE arg, int base)
|
264
|
+
void mpf_set_value2(MP_FLOAT *self_val, VALUE arg, int base, mp_rnd_t rnd_mode_val)
|
265
265
|
{
|
266
266
|
int result;
|
267
267
|
|
268
|
-
|
269
|
-
result = mpfr_set_str (self_val, StringValuePtr (arg), base, __gmp_default_rounding_mode);
|
268
|
+
result = mpfr_set_str (self_val, StringValuePtr (arg), base, rnd_mode_val);
|
270
269
|
|
271
270
|
if (result == -1) {
|
272
271
|
rb_raise (rb_eRuntimeError, "Badly formatted string");
|
273
272
|
}
|
274
273
|
}
|
275
274
|
|
275
|
+
#if MPFR_VERSION_MAJOR > 2
|
276
|
+
VALUE r_gmpfsg_new_2exp(int argc, VALUE *argv, VALUE klass)
|
277
|
+
{
|
278
|
+
MP_FLOAT *res;
|
279
|
+
MP_INT *arg_z;
|
280
|
+
VALUE res_val, arg_val, exp_val, prec_val, rnd_mode_val;
|
281
|
+
mp_rnd_t rnd_mode;
|
282
|
+
(void)klass;
|
283
|
+
|
284
|
+
rb_scan_args (argc, argv, "22", &arg_val, &exp_val, &prec_val, &rnd_mode_val);
|
285
|
+
mpf_make_struct (res_val, res);
|
286
|
+
|
287
|
+
if (!FIXNUM_P (exp_val)) {
|
288
|
+
mpfr_init (res);
|
289
|
+
rb_raise(rb_eTypeError, "exp must be a Fixnum");
|
290
|
+
}
|
291
|
+
|
292
|
+
if (NIL_P (prec_val))
|
293
|
+
mpfr_init (res);
|
294
|
+
else if (FIXNUM_P (prec_val)) {
|
295
|
+
if (FIX2INT (prec_val) >= 0) {
|
296
|
+
mpfr_init2 (res, FIX2INT (prec_val));
|
297
|
+
} else {
|
298
|
+
mpfr_init (res);
|
299
|
+
rb_raise(rb_eRangeError, "precision must be non-negative");
|
300
|
+
}
|
301
|
+
} else {
|
302
|
+
mpfr_init (res);
|
303
|
+
rb_raise(rb_eTypeError, "precision must be a Fixnum");
|
304
|
+
}
|
305
|
+
|
306
|
+
if (NIL_P (rnd_mode_val))
|
307
|
+
rnd_mode = __gmp_default_rounding_mode;
|
308
|
+
else
|
309
|
+
rnd_mode = r_get_rounding_mode (rnd_mode_val);
|
310
|
+
|
311
|
+
if (GMPZ_P (arg_val)) {
|
312
|
+
mpz_get_struct (arg_val, arg_z);
|
313
|
+
mpfr_set_z_2exp (res, arg_z, FIX2NUM (exp_val), rnd_mode);
|
314
|
+
} else if (FIXNUM_P (arg_val)) {
|
315
|
+
mpfr_set_si_2exp (res, FIX2NUM (arg_val), FIX2NUM (exp_val), rnd_mode);
|
316
|
+
} else if (BIGNUM_P (arg_val)) {
|
317
|
+
#if 1 /* GMP3 code */
|
318
|
+
mpz_temp_from_bignum (arg_z, arg_val);
|
319
|
+
mpfr_set_z_2exp (res, arg_z, FIX2NUM (exp_val), rnd_mode);
|
320
|
+
mpz_temp_free (arg_z);
|
321
|
+
#endif /* GMP3 code */
|
322
|
+
} else {
|
323
|
+
rb_raise (rb_eTypeError, "Don't know how to convert %s into GMP::F", rb_class2name (rb_class_of (arg_val)));
|
324
|
+
typeerror_as (ZXB, "value");
|
325
|
+
}
|
326
|
+
|
327
|
+
return res_val;
|
328
|
+
}
|
329
|
+
#endif /* MPFR_VERSION_MAJOR > 2 */
|
330
|
+
|
276
331
|
/*
|
332
|
+
* Document-method: nan
|
277
333
|
* call-seq:
|
278
334
|
* GMP::F.nan
|
279
335
|
*
|
280
|
-
* NaN
|
336
|
+
* `NaN`, an instance of GMP::F
|
337
|
+
*
|
338
|
+
* @since 0.6.47
|
281
339
|
*/
|
282
340
|
VALUE r_gmpfsg_nan(VALUE klass)
|
283
341
|
{
|
@@ -292,18 +350,21 @@ VALUE r_gmpfsg_nan(VALUE klass)
|
|
292
350
|
}
|
293
351
|
|
294
352
|
/*
|
353
|
+
* Document-method: inf
|
295
354
|
* call-seq:
|
296
355
|
* GMP::F.inf
|
297
356
|
* GMP::F.inf(sign)
|
298
357
|
*
|
299
|
-
* Inf (positive infinity), an instance of GMP::F, or
|
300
|
-
* if a negative Fixnum _sign_ is passed
|
358
|
+
* `Inf` (positive infinity), an instance of GMP::F, or `-Inf` (negative
|
359
|
+
* infinity), if a negative Fixnum _sign_ is passed
|
360
|
+
*
|
361
|
+
* @since 0.6.47
|
301
362
|
*/
|
302
363
|
VALUE r_gmpfsg_inf(int argc, VALUE *argv, VALUE klass)
|
303
364
|
{
|
304
365
|
MP_FLOAT *res;
|
305
366
|
VALUE sign_val, res_val;
|
306
|
-
int sign;
|
367
|
+
int sign = 0;
|
307
368
|
(void)klass;
|
308
369
|
|
309
370
|
rb_scan_args (argc, argv, "01", &sign_val);
|
@@ -319,17 +380,20 @@ VALUE r_gmpfsg_inf(int argc, VALUE *argv, VALUE klass)
|
|
319
380
|
|
320
381
|
#if MPFR_VERSION_MAJOR > 2
|
321
382
|
/*
|
383
|
+
* Document-method: zero
|
322
384
|
* call-seq:
|
323
385
|
* GMP::F.zero
|
324
386
|
* GMP::F.zero(sign)
|
325
387
|
*
|
326
388
|
* zero or negative zero, an instance of GMP::F, depending on _sign_, a Fixnum
|
389
|
+
*
|
390
|
+
* @since 0.6.47
|
327
391
|
*/
|
328
392
|
VALUE r_gmpfsg_zero(int argc, VALUE *argv, VALUE klass)
|
329
393
|
{
|
330
394
|
MP_FLOAT *res;
|
331
395
|
VALUE sign_val, res_val;
|
332
|
-
int sign;
|
396
|
+
int sign = 0;
|
333
397
|
(void)klass;
|
334
398
|
|
335
399
|
rb_scan_args (argc, argv, "01", &sign_val);
|
@@ -349,7 +413,7 @@ VALUE r_gmpfsg_zero(int argc, VALUE *argv, VALUE klass)
|
|
349
413
|
* call-seq:
|
350
414
|
* GMP::F(arg)
|
351
415
|
*
|
352
|
-
* A convenience method for
|
416
|
+
* A convenience method for GMP::F.new(arg).
|
353
417
|
*/
|
354
418
|
VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module)
|
355
419
|
{
|
@@ -363,6 +427,7 @@ VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module)
|
|
363
427
|
**********************************************************************/
|
364
428
|
|
365
429
|
/*
|
430
|
+
* Document-method: to_d
|
366
431
|
* call-seq:
|
367
432
|
* x.to_d
|
368
433
|
*
|
@@ -377,6 +442,7 @@ VALUE r_gmpf_to_d(VALUE self)
|
|
377
442
|
}
|
378
443
|
|
379
444
|
/*
|
445
|
+
* Document-method: to_s
|
380
446
|
* call-seq:
|
381
447
|
* x.to_s(base = 10)
|
382
448
|
*
|
@@ -440,10 +506,12 @@ VALUE r_gmpf_to_s(int argc, VALUE *argv, VALUE self_val)
|
|
440
506
|
|
441
507
|
#ifndef MPFR
|
442
508
|
/*
|
509
|
+
* Document-method: +
|
443
510
|
* call-seq:
|
444
511
|
* x + y
|
445
512
|
*
|
446
513
|
* Returns the sum of _x_ and _y_. _y_ must be an instance of:
|
514
|
+
*
|
447
515
|
* * GMP::Z
|
448
516
|
* * Fixnum
|
449
517
|
* * GMP::Q
|
@@ -480,7 +548,7 @@ VALUE r_gmpf_add(VALUE self, VALUE arg)
|
|
480
548
|
mpf_make_struct_init(res, res_val, prec);
|
481
549
|
mpf_set_d (res_val, NUM2DBL(arg));
|
482
550
|
mpf_add (res_val, res_val, self_val);
|
483
|
-
} else if (FIXNUM_P(arg)) {
|
551
|
+
} else if (FIXNUM_P(arg)) { /* TODO: _ui with sign control instead */
|
484
552
|
mpf_make_struct_init(res, res_val, prec);
|
485
553
|
mpf_set_si (res_val, FIX2NUM(arg));
|
486
554
|
mpf_add (res_val, res_val, self_val);
|
@@ -498,10 +566,12 @@ VALUE r_gmpf_add(VALUE self, VALUE arg)
|
|
498
566
|
}
|
499
567
|
#else
|
500
568
|
/*
|
569
|
+
* Document-method: +
|
501
570
|
* call-seq:
|
502
571
|
* x + y
|
503
572
|
*
|
504
573
|
* Returns the sum of _x_ and _y_. _y_ must be an instance of:
|
574
|
+
*
|
505
575
|
* * GMP::Z
|
506
576
|
* * Fixnum
|
507
577
|
* * GMP::Q
|
@@ -564,10 +634,12 @@ DEFUN_F_ZQXFBD2F(mul)
|
|
564
634
|
#endif
|
565
635
|
|
566
636
|
/*
|
637
|
+
* Document-method: -
|
567
638
|
* call-seq:
|
568
639
|
* x - y
|
569
640
|
*
|
570
641
|
* Subtracts _y_ from _x_. _y_ must be an instance of:
|
642
|
+
*
|
571
643
|
* * GMP::Z
|
572
644
|
* * Fixnum
|
573
645
|
* * GMP::Q
|
@@ -580,7 +652,7 @@ VALUE r_gmpf_sub(VALUE self, VALUE arg)
|
|
580
652
|
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
581
653
|
MP_RAT *arg_val_q;
|
582
654
|
MP_INT *arg_val_z;
|
583
|
-
VALUE res;
|
655
|
+
VALUE res = 0;
|
584
656
|
mpfr_prec_t prec;
|
585
657
|
|
586
658
|
mpf_get_struct_prec (self, self_val, prec);
|
@@ -604,7 +676,7 @@ VALUE r_gmpf_sub(VALUE self, VALUE arg)
|
|
604
676
|
mpf_make_struct_init(res, res_val, prec);
|
605
677
|
mpf_set_d(res_val, NUM2DBL(arg));
|
606
678
|
mpf_sub(res_val, self_val, res_val);
|
607
|
-
} else if (FIXNUM_P(arg)) {
|
679
|
+
} else if (FIXNUM_P(arg)) { /* TODO: _ui with sign control instead ? */
|
608
680
|
mpf_make_struct_init(res, res_val, prec);
|
609
681
|
mpf_set_si(res_val, FIX2NUM(arg));
|
610
682
|
mpf_sub(res_val, self_val, res_val);
|
@@ -622,10 +694,12 @@ VALUE r_gmpf_sub(VALUE self, VALUE arg)
|
|
622
694
|
}
|
623
695
|
|
624
696
|
/*
|
697
|
+
* Document-method: *
|
625
698
|
* call-seq:
|
626
699
|
* x * y
|
627
700
|
*
|
628
|
-
* Returns the product of _x_ and _y_. _y_ can be
|
701
|
+
* Returns the product of _x_ and _y_. _y_ can be one of:
|
702
|
+
*
|
629
703
|
* * GMP::Z
|
630
704
|
* * Fixnum
|
631
705
|
* * GMP::Q
|
@@ -638,7 +712,7 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
|
|
638
712
|
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
639
713
|
MP_RAT *arg_val_q;
|
640
714
|
MP_INT *arg_val_z;
|
641
|
-
VALUE res;
|
715
|
+
VALUE res = 0;
|
642
716
|
mpfr_prec_t prec;
|
643
717
|
|
644
718
|
mpf_get_struct_prec (self, self_val, prec);
|
@@ -662,7 +736,7 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
|
|
662
736
|
mpf_make_struct_init(res, res_val, prec);
|
663
737
|
mpf_set_d(res_val, NUM2DBL(arg));
|
664
738
|
mpf_mul(res_val, self_val, res_val);
|
665
|
-
} else if (FIXNUM_P(arg)) {
|
739
|
+
} else if (FIXNUM_P(arg)) { /* _ui with sign control instead ? */
|
666
740
|
mpf_make_struct_init(res, res_val, prec);
|
667
741
|
mpf_set_si(res_val, FIX2NUM(arg));
|
668
742
|
mpf_mul(res_val, self_val, res_val);
|
@@ -680,17 +754,19 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
|
|
680
754
|
}
|
681
755
|
|
682
756
|
/*
|
757
|
+
* Document-method: **
|
683
758
|
* call-seq:
|
684
759
|
* x ** y
|
685
760
|
*
|
686
761
|
* Returns _x_ raised to the _y_ power. _y_ must be
|
762
|
+
*
|
687
763
|
* * an instance of Fixnum or Bignum
|
688
764
|
* * non-negative
|
689
765
|
*/
|
690
766
|
VALUE r_gmpf_pow(VALUE self, VALUE arg)
|
691
767
|
{
|
692
768
|
MP_FLOAT *self_val, *res_val;
|
693
|
-
VALUE res;
|
769
|
+
VALUE res = 0;
|
694
770
|
|
695
771
|
//unsigned long prec;
|
696
772
|
mpfr_prec_t prec;
|
@@ -712,10 +788,12 @@ VALUE r_gmpf_pow(VALUE self, VALUE arg)
|
|
712
788
|
}
|
713
789
|
|
714
790
|
/*
|
791
|
+
* Document-method: /
|
715
792
|
* call-seq:
|
716
793
|
* x / y
|
717
794
|
*
|
718
795
|
* Divides _x_ by _y_. _y_ can be
|
796
|
+
*
|
719
797
|
* * GMP::Z
|
720
798
|
* * Fixnum
|
721
799
|
* * GMP::Q
|
@@ -728,7 +806,7 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
728
806
|
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
729
807
|
MP_RAT *arg_val_q;
|
730
808
|
MP_INT *arg_val_z;
|
731
|
-
VALUE res;
|
809
|
+
VALUE res = 0;
|
732
810
|
mpfr_prec_t prec;
|
733
811
|
|
734
812
|
mpf_get_struct_prec (self, self_val, prec);
|
@@ -752,7 +830,7 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
752
830
|
mpf_make_struct_init(res, res_val, prec);
|
753
831
|
mpf_set_d(res_val, NUM2DBL(arg));
|
754
832
|
mpf_div(res_val, self_val, res_val);
|
755
|
-
} else if (FIXNUM_P(arg)) {
|
833
|
+
} else if (FIXNUM_P(arg)) { /* TODO: _ui with sign control instead */
|
756
834
|
mpf_make_struct_init(res, res_val, prec);
|
757
835
|
mpf_set_si(res_val, FIX2NUM(arg));
|
758
836
|
mpf_div(res_val, self_val, res_val);
|
@@ -760,7 +838,7 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
760
838
|
mpz_temp_from_bignum(arg_val_z, arg);
|
761
839
|
mpf_make_struct_init(res, res_val, prec);
|
762
840
|
mpf_set_z(res_val, arg_val_z);
|
763
|
-
mpf_div(res_val, self_val, res_val);
|
841
|
+
mpf_div(res_val, self_val, res_val);
|
764
842
|
mpz_temp_free(arg_val_z);
|
765
843
|
} else {
|
766
844
|
typeerror(ZQFXBD);
|
@@ -771,10 +849,12 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
771
849
|
|
772
850
|
#ifdef MPFR
|
773
851
|
/*
|
852
|
+
* Document-method: **
|
774
853
|
* call-seq:
|
775
854
|
* float ** other
|
776
855
|
*
|
777
|
-
* Returns _x_ raised to the _y_ power. _y_ must be an instance of
|
856
|
+
* Returns _x_ raised to the _y_ power. _y_ must be an instance of:
|
857
|
+
*
|
778
858
|
* * Fixnum
|
779
859
|
* * Bignum
|
780
860
|
* * Float
|
@@ -825,7 +905,6 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
825
905
|
|
826
906
|
/*
|
827
907
|
* Document-method: neg
|
828
|
-
*
|
829
908
|
* call-seq:
|
830
909
|
* x.neg
|
831
910
|
* -x
|
@@ -834,16 +913,15 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
834
913
|
*/
|
835
914
|
/*
|
836
915
|
* Document-method: neg!
|
837
|
-
*
|
838
916
|
* call-seq:
|
839
917
|
* x.neg!
|
840
918
|
*
|
841
919
|
* Sets _x_ to -_x_.
|
842
920
|
*/
|
843
921
|
DEFUN_FLOAT2FLOAT(neg,mpf_neg)
|
922
|
+
|
844
923
|
/*
|
845
924
|
* Document-method: abs
|
846
|
-
*
|
847
925
|
* call-seq:
|
848
926
|
* x.abs
|
849
927
|
*
|
@@ -851,7 +929,6 @@ DEFUN_FLOAT2FLOAT(neg,mpf_neg)
|
|
851
929
|
*/
|
852
930
|
/*
|
853
931
|
* Document-method: abs!
|
854
|
-
*
|
855
932
|
* call-seq:
|
856
933
|
* x.abs!
|
857
934
|
*
|
@@ -889,19 +966,19 @@ int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
|
|
889
966
|
* what does really "equal" mean ? it's not obvious
|
890
967
|
* Is this a note that I, srawlins, put in here? It is not obvious to me...
|
891
968
|
*/
|
892
|
-
VALUE r_gmpf_eq(VALUE
|
969
|
+
VALUE r_gmpf_eq(VALUE self_val, VALUE arg_val)
|
893
970
|
{
|
894
|
-
MP_FLOAT *
|
895
|
-
mpf_get_struct (self
|
896
|
-
return (mpf_cmp_value(
|
971
|
+
MP_FLOAT *self;
|
972
|
+
mpf_get_struct (self_val, self);
|
973
|
+
return (mpf_cmp_value (self, arg_val) == 0) ? Qtrue : Qfalse;
|
897
974
|
}
|
898
975
|
|
899
|
-
VALUE r_gmpf_cmp(VALUE
|
976
|
+
VALUE r_gmpf_cmp(VALUE self_val, VALUE arg_val)
|
900
977
|
{
|
901
|
-
MP_FLOAT *
|
978
|
+
MP_FLOAT *self;
|
902
979
|
int res;
|
903
|
-
mpf_get_struct (
|
904
|
-
res = mpf_cmp_value (
|
980
|
+
mpf_get_struct (self_val, self);
|
981
|
+
res = mpf_cmp_value (self, arg_val);
|
905
982
|
if (res > 0)
|
906
983
|
return INT2FIX(1);
|
907
984
|
else if (res == 0)
|
@@ -916,25 +993,29 @@ DEFUN_FLOAT_CMP(gt,>)
|
|
916
993
|
DEFUN_FLOAT_CMP(ge,>=)
|
917
994
|
|
918
995
|
/*
|
996
|
+
* Document-method: sgn
|
919
997
|
* call-seq:
|
920
998
|
* x.sgn
|
921
999
|
*
|
922
1000
|
* Returns +1 if _x_ > 0, 0 if _x_ == 0, and -1 if _x_ < 0.
|
923
1001
|
*/
|
924
|
-
VALUE r_gmpf_sgn(VALUE
|
1002
|
+
VALUE r_gmpf_sgn(VALUE self_val)
|
925
1003
|
{
|
926
|
-
MP_FLOAT *
|
927
|
-
mpf_get_struct (
|
928
|
-
return INT2FIX (mpf_sgn (
|
1004
|
+
MP_FLOAT *self;
|
1005
|
+
mpf_get_struct (self_val, self);
|
1006
|
+
return INT2FIX (mpf_sgn (self));
|
929
1007
|
}
|
930
1008
|
|
931
1009
|
#ifdef MPFR
|
932
1010
|
|
933
1011
|
/*
|
1012
|
+
* Document-method: lessgreater?
|
934
1013
|
* call-seq:
|
935
1014
|
* x.lessgreater?(y)
|
936
1015
|
*
|
937
|
-
* Return true if _x_ < _y_ or _x_ > _y_
|
1016
|
+
* Return true if _x_ < _y_ or _x_ > _y_, false otherwise
|
1017
|
+
*
|
1018
|
+
* @since 0.6.47
|
938
1019
|
*/
|
939
1020
|
VALUE r_gmpfr_lessgreater_p(VALUE self_val, VALUE arg_val)
|
940
1021
|
{
|
@@ -949,10 +1030,13 @@ VALUE r_gmpfr_lessgreater_p(VALUE self_val, VALUE arg_val)
|
|
949
1030
|
}
|
950
1031
|
|
951
1032
|
/*
|
1033
|
+
* Document-method: unordered?
|
952
1034
|
* call-seq:
|
953
1035
|
* x.unordered?(y)
|
954
1036
|
*
|
955
|
-
* Return true if _x_ or _y_ is a NaN
|
1037
|
+
* Return true if _x_ or _y_ is a `NaN`, false otherwise
|
1038
|
+
*
|
1039
|
+
* @since 0.6.47
|
956
1040
|
*/
|
957
1041
|
VALUE r_gmpfr_unordered_p(VALUE self_val, VALUE arg_val)
|
958
1042
|
{
|
@@ -980,26 +1064,26 @@ DEFUN_FLOAT2FLOAT(ceil,mpf_ceil)
|
|
980
1064
|
|
981
1065
|
#ifdef MPFR
|
982
1066
|
|
983
|
-
#define MPFR_SINGLE_FUNCTION(name)
|
984
|
-
VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE
|
985
|
-
{
|
986
|
-
MP_FLOAT *
|
987
|
-
VALUE
|
988
|
-
mpfr_prec_t prec,
|
989
|
-
mp_rnd_t
|
990
|
-
|
991
|
-
mpf_get_struct_prec (
|
992
|
-
|
993
|
-
rb_scan_args (argc, argv, "02", &
|
994
|
-
if (NIL_P (
|
995
|
-
else {
|
996
|
-
if (NIL_P (
|
997
|
-
|
998
|
-
else {
|
999
|
-
mpf_make_struct_init (
|
1000
|
-
mpfr_##name (
|
1001
|
-
|
1002
|
-
return
|
1067
|
+
#define MPFR_SINGLE_FUNCTION(name) \
|
1068
|
+
VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self_val) \
|
1069
|
+
{ \
|
1070
|
+
MP_FLOAT *self, *res; \
|
1071
|
+
VALUE rnd_mode_val, res_prec_val, res_val; \
|
1072
|
+
mpfr_prec_t prec, res_prec; \
|
1073
|
+
mp_rnd_t rnd_mode; \
|
1074
|
+
\
|
1075
|
+
mpf_get_struct_prec (self_val, self, prec); \
|
1076
|
+
\
|
1077
|
+
rb_scan_args (argc, argv, "02", &rnd_mode_val, &res_prec_val); \
|
1078
|
+
if (NIL_P (rnd_mode_val)) { rnd_mode = __gmp_default_rounding_mode; } \
|
1079
|
+
else { rnd_mode = r_get_rounding_mode(rnd_mode_val); } \
|
1080
|
+
if (NIL_P (res_prec_val)) { res_prec = prec; } \
|
1081
|
+
else if (FIXNUM_P (res_prec_val)) { res_prec = FIX2INT (res_prec_val); } \
|
1082
|
+
else { typeerror_as (X, "precision"); } \
|
1083
|
+
mpf_make_struct_init (res_val, res, res_prec); \
|
1084
|
+
mpfr_##name (res, self, rnd_mode); \
|
1085
|
+
\
|
1086
|
+
return res_val; \
|
1003
1087
|
}
|
1004
1088
|
|
1005
1089
|
#define MPFR_DOUBLE_FUNCTION(name) \
|
@@ -1061,15 +1145,24 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
|
1061
1145
|
rb_scan_args (argc, argv, "12", &arg1, &rnd_mode, &res_prec); \
|
1062
1146
|
\
|
1063
1147
|
mpf_get_struct_prec (self, self_val, prec); \
|
1064
|
-
if (
|
1065
|
-
|
1148
|
+
if (GMPF_P (arg1)) { \
|
1149
|
+
mpf_get_struct_prec (arg1, arg1_val, arg1_prec); \
|
1150
|
+
} else if (FLOAT_P (arg1)) { \
|
1151
|
+
mpf_temp_init(arg1_val, mpf_get_prec (self_val)); \
|
1152
|
+
mpfr_set_d (arg1_val, NUM2DBL (arg1), __gmp_default_rounding_mode); \
|
1153
|
+
} else { \
|
1154
|
+
typeerror (FD); \
|
1155
|
+
} \
|
1066
1156
|
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
1067
1157
|
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
1068
1158
|
if (NIL_P (res_prec)) { res_prec_value = prec; } \
|
1069
1159
|
/* TODO test type */ \
|
1070
1160
|
else { res_prec_value = FIX2INT (res_prec); } \
|
1071
1161
|
mpf_make_struct_init (res, res_val, res_prec_value); \
|
1072
|
-
mpfr_##name (res_val,
|
1162
|
+
mpfr_##name (res_val, self_val, arg1_val, rnd_mode_val); \
|
1163
|
+
if (FLOAT_P (arg1)) { \
|
1164
|
+
mpf_temp_free(arg1_val); \
|
1165
|
+
} \
|
1073
1166
|
\
|
1074
1167
|
return res; \
|
1075
1168
|
}
|
@@ -1094,7 +1187,7 @@ VALUE r_gmpfrsg_##name(int argc, VALUE *argv, VALUE self) \
|
|
1094
1187
|
VALUE res; \
|
1095
1188
|
VALUE rnd_mode, prec; \
|
1096
1189
|
mp_rnd_t rnd_mode_val; \
|
1097
|
-
mpfr_prec_t prec_val;
|
1190
|
+
mpfr_prec_t prec_val = 0; \
|
1098
1191
|
(void)self; \
|
1099
1192
|
\
|
1100
1193
|
rb_scan_args (argc, argv, "02", &rnd_mode, &prec); \
|
@@ -1103,7 +1196,7 @@ VALUE r_gmpfrsg_##name(int argc, VALUE *argv, VALUE self) \
|
|
1103
1196
|
else { rnd_mode_val = r_get_rounding_mode (rnd_mode); } \
|
1104
1197
|
if (NIL_P (prec)) { prec_val = mpfr_get_default_prec(); } \
|
1105
1198
|
else if (FIXNUM_P (prec)) { prec_val = FIX2INT (prec); } \
|
1106
|
-
else { typeerror_as (
|
1199
|
+
else { typeerror_as (X, "precision"); } \
|
1107
1200
|
mpf_make_struct_init (res, res_val, prec_val); \
|
1108
1201
|
mpfr_##name (res_val, rnd_mode_val); \
|
1109
1202
|
\
|
@@ -1111,14 +1204,17 @@ VALUE r_gmpfrsg_##name(int argc, VALUE *argv, VALUE self) \
|
|
1111
1204
|
}
|
1112
1205
|
|
1113
1206
|
/*
|
1207
|
+
* Document-method: frexp
|
1114
1208
|
* call-seq:
|
1115
1209
|
* exp, y = x.frexp(rnd_mode = nil, prec = nil)
|
1116
1210
|
*
|
1117
|
-
* Set _exp_ and _y_ such that
|
1118
|
-
*
|
1119
|
-
*
|
1120
|
-
*
|
1121
|
-
*
|
1211
|
+
* Set _exp_ and _y_ such that 0.5 <= _abs(y)_ < 1 and _y_ times 2 raised to
|
1212
|
+
* _exp_ equals _x_ rounded to _prec_, or the precision of _x_, using the given
|
1213
|
+
* rounding mode. If _x_ is zero, then _y_ is set to a zero of the same sign
|
1214
|
+
* and _exp_ is set to 0. If _x_ is `NaN` or an infinity, then _y_ is set to
|
1215
|
+
* the same value and _exp_ is undefined.
|
1216
|
+
*
|
1217
|
+
* @since 0.6.47
|
1122
1218
|
*/
|
1123
1219
|
VALUE r_gmpfr_frexp(int argc, VALUE *argv, VALUE self_val)
|
1124
1220
|
{
|
@@ -1142,22 +1238,212 @@ VALUE r_gmpfr_frexp(int argc, VALUE *argv, VALUE self_val)
|
|
1142
1238
|
return rb_assoc_new(exp_val, res_val);
|
1143
1239
|
}
|
1144
1240
|
|
1241
|
+
/*
|
1242
|
+
* Document-method: sqrt
|
1243
|
+
* call-seq:
|
1244
|
+
* x.sqrt
|
1245
|
+
* x.sqrt(rounding_mode)
|
1246
|
+
* x.sqrt(rounding_mode, precision)
|
1247
|
+
*
|
1248
|
+
* Calculate the square root of _x_, rounding according to `rounding_mode`. The
|
1249
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1250
|
+
* was not passed in.
|
1251
|
+
*/
|
1145
1252
|
MPFR_SINGLE_FUNCTION(sqrt)
|
1253
|
+
|
1254
|
+
/*
|
1255
|
+
* Document-method: rec_sqrt
|
1256
|
+
* call-seq:
|
1257
|
+
* x.rec_sqrt
|
1258
|
+
* x.rec_sqrt(rounding_mode)
|
1259
|
+
* x.rec_sqrt(rounding_mode, precision)
|
1260
|
+
*
|
1261
|
+
* Calculate the reciprocal square root of _x_, rounding according to
|
1262
|
+
* `rounding_mode`. The resultant GMP::F float has the same precision that _x_
|
1263
|
+
* has, if `precision` was not passed in.
|
1264
|
+
*/
|
1146
1265
|
MPFR_SINGLE_FUNCTION(rec_sqrt)
|
1266
|
+
|
1267
|
+
/*
|
1268
|
+
* Document-method: cbrt
|
1269
|
+
* call-seq:
|
1270
|
+
* x.cbrt
|
1271
|
+
* x.cbrt(rounding_mode)
|
1272
|
+
* x.cbrt(rounding_mode, precision)
|
1273
|
+
*
|
1274
|
+
* Calculate the cubic root of _x_, rounding according to `rounding_mode`. The
|
1275
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1276
|
+
* was not passed in.
|
1277
|
+
*/
|
1147
1278
|
MPFR_SINGLE_FUNCTION(cbrt)
|
1148
1279
|
|
1280
|
+
/*
|
1281
|
+
* Document-method: log
|
1282
|
+
* call-seq:
|
1283
|
+
* x.log
|
1284
|
+
* x.log(rounding_mode)
|
1285
|
+
* x.log(rounding_mode, precision)
|
1286
|
+
*
|
1287
|
+
* Calculate the natural logarithm of _x_, rounding according to
|
1288
|
+
* `rounding_mode`. The resultant GMP::F float has the same precision that _x_
|
1289
|
+
* has, if `precision` was not passed in.
|
1290
|
+
*/
|
1149
1291
|
MPFR_SINGLE_FUNCTION(log)
|
1292
|
+
|
1293
|
+
/*
|
1294
|
+
* Document-method: log2
|
1295
|
+
* call-seq:
|
1296
|
+
* x.log2
|
1297
|
+
* x.log2(rounding_mode)
|
1298
|
+
* x.log2(rounding_mode, precision)
|
1299
|
+
*
|
1300
|
+
* Calculate the logarithm base 2 of _x_, rounding according to
|
1301
|
+
* `rounding_mode`. The resultant GMP::F float has the same precision that _x_
|
1302
|
+
* has, if `precision` was not passed in.
|
1303
|
+
*/
|
1150
1304
|
MPFR_SINGLE_FUNCTION(log2)
|
1305
|
+
|
1306
|
+
/*
|
1307
|
+
* Document-method: log10
|
1308
|
+
* call-seq:
|
1309
|
+
* x.log10
|
1310
|
+
* x.log10(rounding_mode)
|
1311
|
+
* x.log10(rounding_mode, precision)
|
1312
|
+
*
|
1313
|
+
* Calculate the logarithm base 10 of _x_, rounding according to
|
1314
|
+
* `rounding_mode`. The resultant GMP::F float has the same precision that _x_
|
1315
|
+
* has, if `precision` was not passed in.
|
1316
|
+
*/
|
1151
1317
|
MPFR_SINGLE_FUNCTION(log10)
|
1318
|
+
|
1319
|
+
/*
|
1320
|
+
* Document-method: exp
|
1321
|
+
* call-seq:
|
1322
|
+
* x.exp
|
1323
|
+
* x.exp(rounding_mode)
|
1324
|
+
* x.exp(rounding_mode, precision)
|
1325
|
+
*
|
1326
|
+
* Calculate the exponential of _x_, rounding according to `rounding_mode`. The
|
1327
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1328
|
+
* was not passed in.
|
1329
|
+
*/
|
1152
1330
|
MPFR_SINGLE_FUNCTION(exp)
|
1331
|
+
|
1332
|
+
/*
|
1333
|
+
* Document-method: exp2
|
1334
|
+
* call-seq:
|
1335
|
+
* x.exp2
|
1336
|
+
* x.exp2(rounding_mode)
|
1337
|
+
* x.exp2(rounding_mode, precision)
|
1338
|
+
*
|
1339
|
+
* Calculate the 2 power of _x_, rounding according to `rounding_mode`. The
|
1340
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1341
|
+
* was not passed in.
|
1342
|
+
*/
|
1153
1343
|
MPFR_SINGLE_FUNCTION(exp2)
|
1344
|
+
|
1345
|
+
/*
|
1346
|
+
* Document-method: exp10
|
1347
|
+
* call-seq:
|
1348
|
+
* x.exp10
|
1349
|
+
* x.exp10(rounding_mode)
|
1350
|
+
* x.exp10(rounding_mode, precision)
|
1351
|
+
*
|
1352
|
+
* Calculate the 10 power of _x_, rounding according to `rounding_mode`. The
|
1353
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1354
|
+
* was not passed in.
|
1355
|
+
*/
|
1154
1356
|
MPFR_SINGLE_FUNCTION(exp10)
|
1357
|
+
|
1358
|
+
/*
|
1359
|
+
* Document-method: cos
|
1360
|
+
* call-seq:
|
1361
|
+
* x.cos
|
1362
|
+
* x.cos(rounding_mode)
|
1363
|
+
* x.cos(rounding_mode, precision)
|
1364
|
+
*
|
1365
|
+
* Calculate the cosine of _x_, rounding according to `rounding_mode`. The
|
1366
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1367
|
+
* was not passed in.
|
1368
|
+
*/
|
1155
1369
|
MPFR_SINGLE_FUNCTION(cos)
|
1370
|
+
|
1371
|
+
/*
|
1372
|
+
* Document-method: sin
|
1373
|
+
* call-seq:
|
1374
|
+
* x.sin
|
1375
|
+
* x.sin(rounding_mode)
|
1376
|
+
* x.sin(rounding_mode, precision)
|
1377
|
+
*
|
1378
|
+
* Calculate the sine of _x_, rounding according to `rounding_mode`. The
|
1379
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1380
|
+
* was not passed in.
|
1381
|
+
*/
|
1156
1382
|
MPFR_SINGLE_FUNCTION(sin)
|
1383
|
+
|
1384
|
+
/*
|
1385
|
+
* Document-method: tan
|
1386
|
+
* call-seq:
|
1387
|
+
* x.tan
|
1388
|
+
* x.tan(rounding_mode)
|
1389
|
+
* x.tan(rounding_mode, precision)
|
1390
|
+
*
|
1391
|
+
* Calculate the tangent of _x_, rounding according to `rounding_mode`. The
|
1392
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1393
|
+
* was not passed in.
|
1394
|
+
*/
|
1157
1395
|
MPFR_SINGLE_FUNCTION(tan)
|
1396
|
+
|
1397
|
+
/*
|
1398
|
+
* Document-method: sin_cos
|
1399
|
+
* call-seq:
|
1400
|
+
* x.sin_cos
|
1401
|
+
* x.sin_cos(rounding_mode)
|
1402
|
+
* x.sin_cos(rounding_mode, precision)
|
1403
|
+
*
|
1404
|
+
* Simultaneously calculate the sine and cosine of _x_, rounding according to
|
1405
|
+
* `rounding_mode`, returning both numbers. The resultant GMP::F floats have
|
1406
|
+
* the same precision that _x_ has, if `precision` was not passed in.
|
1407
|
+
*/
|
1158
1408
|
MPFR_DOUBLE_FUNCTION(sin_cos)
|
1409
|
+
|
1410
|
+
/*
|
1411
|
+
* Document-method: secant
|
1412
|
+
* call-seq:
|
1413
|
+
* x.secant
|
1414
|
+
* x.secant(rounding_mode)
|
1415
|
+
* x.secant(rounding_mode, precision)
|
1416
|
+
*
|
1417
|
+
* Calculate the secant of _x_, rounding according to `rounding_mode`. The
|
1418
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1419
|
+
* was not passed in.
|
1420
|
+
*/
|
1159
1421
|
MPFR_SINGLE_FUNCTION(sec)
|
1422
|
+
|
1423
|
+
/*
|
1424
|
+
* Document-method: csc
|
1425
|
+
* call-seq:
|
1426
|
+
* x.csc
|
1427
|
+
* x.csc(rounding_mode)
|
1428
|
+
* x.csc(rounding_mode, precision)
|
1429
|
+
*
|
1430
|
+
* Calculate the cosecant of _x_, rounding according to `rounding_mode`. The
|
1431
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1432
|
+
* was not passed in.
|
1433
|
+
*/
|
1160
1434
|
MPFR_SINGLE_FUNCTION(csc)
|
1435
|
+
|
1436
|
+
/*
|
1437
|
+
* Document-method: cot
|
1438
|
+
* call-seq:
|
1439
|
+
* x.cot
|
1440
|
+
* x.cot(rounding_mode)
|
1441
|
+
* x.cot(rounding_mode, precision)
|
1442
|
+
*
|
1443
|
+
* Calculate the cotangent of _x_, rounding according to `rounding_mode`. The
|
1444
|
+
* resultant GMP::F float has the same precision that _x_ has, if `precision`
|
1445
|
+
* was not passed in.
|
1446
|
+
*/
|
1161
1447
|
MPFR_SINGLE_FUNCTION(cot)
|
1162
1448
|
MPFR_SINGLE_FUNCTION(acos)
|
1163
1449
|
MPFR_SINGLE_FUNCTION(asin)
|
@@ -1206,6 +1492,8 @@ MPFR_SINGLE_MPF_FUNCTION(hypot)
|
|
1206
1492
|
* Creates a new GMP::F float, equal to the factorial of n, which must be a
|
1207
1493
|
* Fixnum. Optionally pass a rounding mode, and precision for the resultant
|
1208
1494
|
* GMP::F.
|
1495
|
+
*
|
1496
|
+
* @since 0.6.47
|
1209
1497
|
*/
|
1210
1498
|
VALUE r_gmpfrsg_fac(int argc, VALUE *argv, VALUE self_val)
|
1211
1499
|
{
|
@@ -1214,7 +1502,7 @@ VALUE r_gmpfrsg_fac(int argc, VALUE *argv, VALUE self_val)
|
|
1214
1502
|
VALUE rnd_mode_val, prec_val;
|
1215
1503
|
mp_rnd_t rnd_mode;
|
1216
1504
|
mpfr_prec_t prec;
|
1217
|
-
unsigned long int arg;
|
1505
|
+
unsigned long int arg = 0;
|
1218
1506
|
(void)self_val;
|
1219
1507
|
|
1220
1508
|
rb_scan_args (argc, argv, "12", &arg_val, &rnd_mode_val, &prec_val);
|
@@ -1279,54 +1567,62 @@ MPFR_SINGLE_BOOLEAN_FUNCTION(zero_p)
|
|
1279
1567
|
MPFR_SINGLE_BOOLEAN_FUNCTION(regular_p)
|
1280
1568
|
#endif
|
1281
1569
|
|
1282
|
-
static VALUE r_gmpfr_pow(VALUE
|
1570
|
+
static VALUE r_gmpfr_pow(VALUE self_val, VALUE arg_val)
|
1283
1571
|
{
|
1284
|
-
MP_FLOAT *
|
1285
|
-
MP_RAT *
|
1286
|
-
MP_INT *
|
1572
|
+
MP_FLOAT *self, *res, *arg_f;
|
1573
|
+
MP_RAT *arg_q;
|
1574
|
+
MP_INT *arg_z;
|
1287
1575
|
mpfr_prec_t prec;
|
1288
|
-
VALUE
|
1576
|
+
VALUE res_val;
|
1289
1577
|
|
1290
|
-
mpf_get_struct_prec(
|
1578
|
+
mpf_get_struct_prec (self_val, self, prec);
|
1291
1579
|
|
1292
|
-
if (GMPF_P(
|
1293
|
-
mpf_get_struct(
|
1294
|
-
prec_max(prec,
|
1295
|
-
mpf_make_struct_init(
|
1296
|
-
mpfr_pow(
|
1580
|
+
if (GMPF_P (arg_val)) {
|
1581
|
+
mpf_get_struct (arg_val, arg_f);
|
1582
|
+
prec_max (prec, arg_f);
|
1583
|
+
mpf_make_struct_init (res_val, res, prec);
|
1584
|
+
mpfr_pow (res, self, arg_f, __gmp_default_rounding_mode);
|
1297
1585
|
} else {
|
1298
|
-
mpf_make_struct_init(
|
1299
|
-
|
1300
|
-
if (GMPZ_P(
|
1301
|
-
mpz_get_struct(
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1586
|
+
mpf_make_struct_init (res_val, res, prec);
|
1587
|
+
|
1588
|
+
if (GMPZ_P (arg_val)) {
|
1589
|
+
mpz_get_struct (arg_val, arg_z);
|
1590
|
+
mpfr_pow_z (res, self, arg_z, __gmp_default_rounding_mode);
|
1591
|
+
} else if (GMPQ_P (arg_val)) {
|
1592
|
+
mpq_get_struct (arg_val, arg_q);
|
1593
|
+
mpf_set_q (res, arg_q);
|
1594
|
+
mpfr_pow (res, self, res, __gmp_default_rounding_mode);
|
1595
|
+
} else if (FLOAT_P (arg_val)) {
|
1596
|
+
mpf_set_d (res, NUM2DBL (arg_val));
|
1597
|
+
mpfr_pow (res, self, res, __gmp_default_rounding_mode);
|
1598
|
+
} else if (FIXNUM_P (arg_val)) {
|
1599
|
+
if (FIX2NUM (arg_val) >= 0)
|
1600
|
+
mpfr_pow_ui (res, self, FIX2NUM (arg_val), __gmp_default_rounding_mode);
|
1601
|
+
else
|
1602
|
+
mpfr_pow_si (res, self, FIX2NUM (arg_val), __gmp_default_rounding_mode);
|
1603
|
+
} else if (BIGNUM_P (arg_val)) {
|
1604
|
+
mpz_temp_from_bignum (arg_z, arg_val);
|
1605
|
+
mpf_set_z (res, arg_z);
|
1606
|
+
mpz_temp_free (arg_z);
|
1607
|
+
mpfr_pow (res, self, res, __gmp_default_rounding_mode);
|
1318
1608
|
} else {
|
1319
|
-
typeerror(ZQFXBD);
|
1609
|
+
typeerror (ZQFXBD);
|
1320
1610
|
}
|
1321
1611
|
}
|
1322
1612
|
|
1323
|
-
return
|
1613
|
+
return res_val;
|
1324
1614
|
}
|
1325
1615
|
|
1326
1616
|
/**********************************************************************
|
1327
1617
|
* Rounding Related Functions *
|
1328
1618
|
**********************************************************************/
|
1329
1619
|
|
1620
|
+
/*
|
1621
|
+
* call-seq:
|
1622
|
+
* GMP::F.default_rounding_mode
|
1623
|
+
*
|
1624
|
+
* Get the default rounding mode.
|
1625
|
+
*/
|
1330
1626
|
VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
|
1331
1627
|
{
|
1332
1628
|
const char *rounding_string_val;
|
@@ -1340,17 +1636,25 @@ VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
|
|
1340
1636
|
}
|
1341
1637
|
}
|
1342
1638
|
|
1639
|
+
/*
|
1640
|
+
* call-seq:
|
1641
|
+
* GMP::F.default_rounding_mode=(rnd)
|
1642
|
+
*
|
1643
|
+
* Set the default rounding mode to _rnd_. The default rounding mode is to
|
1644
|
+
* nearest initially.
|
1645
|
+
*/
|
1343
1646
|
VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
|
1344
1647
|
{
|
1345
|
-
VALUE mode;
|
1648
|
+
VALUE mode = 0;
|
1346
1649
|
(void)klass;
|
1347
|
-
|
1650
|
+
|
1651
|
+
if (GMPRND_P (arg)) {
|
1348
1652
|
mode = rb_funcall (arg, rb_intern("mode"), 0);
|
1349
|
-
if (FIX2INT(mode) < 0 || FIX2INT(mode) > 3) {
|
1350
|
-
rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
|
1653
|
+
if (FIX2INT (mode) < 0 || FIX2INT (mode) > 3) {
|
1654
|
+
rb_raise (rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
|
1351
1655
|
}
|
1352
1656
|
} else {
|
1353
|
-
rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
1657
|
+
rb_raise (rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
1354
1658
|
}
|
1355
1659
|
|
1356
1660
|
switch (FIX2INT(mode)) {
|
@@ -1374,18 +1678,15 @@ VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
|
|
1374
1678
|
VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec)
|
1375
1679
|
{
|
1376
1680
|
MP_FLOAT *self_val;
|
1377
|
-
mp_exp_t err_val;
|
1681
|
+
mp_exp_t err_val = 0;
|
1378
1682
|
mpfr_rnd_t rnd1_val, rnd2_val;
|
1379
1683
|
mpfr_prec_t prec_val;
|
1380
1684
|
|
1381
|
-
mpf_get_struct(self, self_val);
|
1382
|
-
if (FIXNUM_P(err)) {
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
}
|
1387
|
-
rnd1_val = r_get_rounding_mode(rnd1);
|
1388
|
-
rnd2_val = r_get_rounding_mode(rnd2);
|
1685
|
+
mpf_get_struct (self, self_val);
|
1686
|
+
if (FIXNUM_P (err)) { err_val = FIX2INT (err); }
|
1687
|
+
else { typeerror_as (X, "err"); }
|
1688
|
+
rnd1_val = r_get_rounding_mode (rnd1);
|
1689
|
+
rnd2_val = r_get_rounding_mode (rnd2);
|
1389
1690
|
prec_val = FIX2INT (prec);
|
1390
1691
|
|
1391
1692
|
if (mpfr_can_round (self_val, err_val, rnd1_val, rnd2_val, prec_val))
|
@@ -1396,28 +1697,53 @@ VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec
|
|
1396
1697
|
|
1397
1698
|
|
1398
1699
|
/**********************************************************************
|
1399
|
-
*
|
1700
|
+
* _unsorted_ *
|
1400
1701
|
**********************************************************************/
|
1401
1702
|
|
1703
|
+
/*
|
1704
|
+
* call-seq:
|
1705
|
+
* GMP::F.mpfr_buildopt_tls_p
|
1706
|
+
*
|
1707
|
+
* Return a non-zero value if MPFR was compiled as thread safe using
|
1708
|
+
* compiler-level Thread Local Storage (that is, MPFR was built with the
|
1709
|
+
* --enable-thread-safe configure option, see INSTALL file), return zero
|
1710
|
+
* otherwise.
|
1711
|
+
*/
|
1402
1712
|
VALUE r_gmpfsg_mpfr_buildopt_tls_p(VALUE klass)
|
1403
1713
|
{
|
1404
1714
|
(void)klass;
|
1405
1715
|
return INT2FIX (mpfr_buildopt_tls_p());
|
1406
1716
|
}
|
1407
1717
|
|
1718
|
+
/*
|
1719
|
+
* call-seq:
|
1720
|
+
* GMP::F.mpfr_buildopt_decimal_p
|
1721
|
+
*
|
1722
|
+
* Return a non-zero value if MPFR was compiled with decimal float support
|
1723
|
+
* (that is, MPFR was built with the --enable-decimal-float configure option),
|
1724
|
+
* return zero otherwise.
|
1725
|
+
*/
|
1408
1726
|
VALUE r_gmpfsg_mpfr_buildopt_decimal_p(VALUE klass)
|
1409
1727
|
{
|
1410
1728
|
(void)klass;
|
1411
1729
|
return INT2FIX (mpfr_buildopt_decimal_p());
|
1412
1730
|
}
|
1413
1731
|
|
1414
|
-
#endif
|
1732
|
+
#endif /* MPFR */
|
1415
1733
|
|
1416
1734
|
|
1417
1735
|
/**********************************************************************
|
1418
1736
|
* _unsorted_ *
|
1419
1737
|
**********************************************************************/
|
1420
1738
|
|
1739
|
+
/*
|
1740
|
+
* Document-method: prec
|
1741
|
+
* call-seq:
|
1742
|
+
* x.prec
|
1743
|
+
*
|
1744
|
+
* Return the precision of _x_, i.e. the number of bits used to store its
|
1745
|
+
* significand.
|
1746
|
+
*/
|
1421
1747
|
VALUE r_gmpf_get_prec(VALUE self)
|
1422
1748
|
{
|
1423
1749
|
MP_FLOAT *self_val;
|
@@ -1425,6 +1751,16 @@ VALUE r_gmpf_get_prec(VALUE self)
|
|
1425
1751
|
return INT2NUM (mpf_get_prec (self_val));
|
1426
1752
|
}
|
1427
1753
|
|
1754
|
+
/*
|
1755
|
+
* Document-method: prec=
|
1756
|
+
* call-seq:
|
1757
|
+
* x.prec=(p)
|
1758
|
+
*
|
1759
|
+
* Reset the precision of _x_ to be exactly _p_ bits, and set its value to
|
1760
|
+
* NaN. The previous value stored in _x_ is lost.
|
1761
|
+
* The precision prec can be any integer between
|
1762
|
+
* `MPFR_PREC_MIN` and `MPFR_PREC_MAX`.
|
1763
|
+
*/
|
1428
1764
|
VALUE r_gmpf_set_prec(VALUE self, VALUE arg)
|
1429
1765
|
{
|
1430
1766
|
MP_FLOAT *self_val;
|
@@ -1435,6 +1771,8 @@ VALUE r_gmpf_set_prec(VALUE self, VALUE arg)
|
|
1435
1771
|
} else {
|
1436
1772
|
typeerror(X);
|
1437
1773
|
}
|
1774
|
+
|
1775
|
+
return Qnil; /* should never get here */
|
1438
1776
|
}
|
1439
1777
|
|
1440
1778
|
VALUE r_gmpf_set_prec_raw(VALUE self, VALUE arg)
|
@@ -1447,8 +1785,140 @@ VALUE r_gmpf_set_prec_raw(VALUE self, VALUE arg)
|
|
1447
1785
|
} else {
|
1448
1786
|
typeerror(X);
|
1449
1787
|
}
|
1788
|
+
|
1789
|
+
return Qnil; /* should never get here */
|
1790
|
+
}
|
1791
|
+
|
1792
|
+
#ifdef MPFR
|
1793
|
+
|
1794
|
+
#define DEFUN_FR_CLASS_M(fname,mpfr_fname) \
|
1795
|
+
static VALUE r_gmpfrsg_get_##fname(VALUE klass) \
|
1796
|
+
{ \
|
1797
|
+
(void)klass; \
|
1798
|
+
return INT2NUM (mpfr_fname ()); \
|
1799
|
+
}
|
1800
|
+
|
1801
|
+
/*
|
1802
|
+
* Document-method: GMP::F.emin
|
1803
|
+
* call-seq:
|
1804
|
+
* GMP::F.emin
|
1805
|
+
*
|
1806
|
+
* Return the (current) smallest exponent allowed for a
|
1807
|
+
* floating-point variable. The smallest positive value of a floating-point
|
1808
|
+
* variable is one half times 2 raised to the smallest exponent.
|
1809
|
+
*
|
1810
|
+
* @since 0.7.19
|
1811
|
+
*/
|
1812
|
+
DEFUN_FR_CLASS_M(emin,mpfr_get_emin)
|
1813
|
+
|
1814
|
+
/*
|
1815
|
+
* Document-method: GMP::F.emax
|
1816
|
+
* call-seq:
|
1817
|
+
* GMP::F.emax
|
1818
|
+
*
|
1819
|
+
* Return the (current) largest exponent allowed for a floating-point variable.
|
1820
|
+
* The largest floating-point value has the form (1 - epsilon) times 2 raised
|
1821
|
+
* to the largest exponent, where epsilon depends on the precision of the
|
1822
|
+
* considered variable.
|
1823
|
+
*
|
1824
|
+
* @since 0.7.19
|
1825
|
+
*/
|
1826
|
+
DEFUN_FR_CLASS_M(emax,mpfr_get_emax)
|
1827
|
+
|
1828
|
+
/*
|
1829
|
+
* Document-method: GMP::F.emin_min
|
1830
|
+
* call-seq:
|
1831
|
+
* GMP::F.emin_min
|
1832
|
+
*
|
1833
|
+
* Return the minimum exponent allowed for GMP::F.emin=()
|
1834
|
+
*
|
1835
|
+
* @since 0.7.19
|
1836
|
+
*/
|
1837
|
+
DEFUN_FR_CLASS_M(emin_min,mpfr_get_emin_min)
|
1838
|
+
|
1839
|
+
/*
|
1840
|
+
* Document-method: GMP::F.emin_max
|
1841
|
+
* call-seq:
|
1842
|
+
* GMP::F.emin_max
|
1843
|
+
*
|
1844
|
+
* Return the maximum exponent allowed for GMP::F.emin=()
|
1845
|
+
*
|
1846
|
+
* @since 0.7.19
|
1847
|
+
*/
|
1848
|
+
DEFUN_FR_CLASS_M(emin_max,mpfr_get_emin_max)
|
1849
|
+
|
1850
|
+
/*
|
1851
|
+
* Document-method: GMP::F.emax_min
|
1852
|
+
* call-seq:
|
1853
|
+
* GMP::F.emax_min
|
1854
|
+
*
|
1855
|
+
* Return the minimum exponent allowed for GMP::F.emax=()
|
1856
|
+
*
|
1857
|
+
* @since 0.7.19
|
1858
|
+
*/
|
1859
|
+
DEFUN_FR_CLASS_M(emax_min,mpfr_get_emax_min)
|
1860
|
+
|
1861
|
+
/*
|
1862
|
+
* Document-method: GMP::F.emax_max
|
1863
|
+
* call-seq:
|
1864
|
+
* GMP::F.emax_max
|
1865
|
+
*
|
1866
|
+
* Return the maximum exponent allowed for GMP::F.emax=()
|
1867
|
+
*
|
1868
|
+
* @since 0.7.19
|
1869
|
+
*/
|
1870
|
+
DEFUN_FR_CLASS_M(emax_max,mpfr_get_emax_max)
|
1871
|
+
|
1872
|
+
/*
|
1873
|
+
* Document-method: GMP::F.emin=
|
1874
|
+
* call-seq:
|
1875
|
+
* GMP::F.emin=(exp)
|
1876
|
+
*
|
1877
|
+
* Set the smallest exponent allowed for a floating-point variable.
|
1878
|
+
*
|
1879
|
+
* @since 0.7.19
|
1880
|
+
*/
|
1881
|
+
VALUE r_gmpfrsg_set_emin(VALUE klass, VALUE arg_val)
|
1882
|
+
{
|
1883
|
+
(void)klass;
|
1884
|
+
|
1885
|
+
if (! FIXNUM_P (arg_val))
|
1886
|
+
typeerror_as (X, "exp");
|
1887
|
+
|
1888
|
+
mpfr_set_emin (FIX2NUM (arg_val));
|
1889
|
+
/* TODO: figure out a way to generate this RangeError:
|
1890
|
+
if (success != 0)
|
1891
|
+
rb_raise(rb_eRangeError, "exp must be in-range");*/
|
1892
|
+
|
1893
|
+
return Qnil;
|
1450
1894
|
}
|
1451
1895
|
|
1896
|
+
/*
|
1897
|
+
* Document-method: GMP::F.emax=
|
1898
|
+
* call-seq:
|
1899
|
+
* GMP::F.emax=(exp)
|
1900
|
+
*
|
1901
|
+
* Set the largest exponent allowed for a floating-point variable.
|
1902
|
+
*
|
1903
|
+
* @since 0.7.19
|
1904
|
+
*/
|
1905
|
+
VALUE r_gmpfrsg_set_emax(VALUE klass, VALUE arg_val)
|
1906
|
+
{
|
1907
|
+
(void)klass;
|
1908
|
+
|
1909
|
+
if (! FIXNUM_P (arg_val))
|
1910
|
+
typeerror_as (X, "exp");
|
1911
|
+
|
1912
|
+
mpfr_set_emax (FIX2NUM (arg_val));
|
1913
|
+
/* TODO: figure out a way to generate this RangeError:
|
1914
|
+
if (success != 0)
|
1915
|
+
rb_raise(rb_eRangeError, "exp must be in-range");*/
|
1916
|
+
|
1917
|
+
return Qnil;
|
1918
|
+
}
|
1919
|
+
|
1920
|
+
#endif /* MPFR */
|
1921
|
+
|
1452
1922
|
|
1453
1923
|
void init_gmpf()
|
1454
1924
|
{
|
@@ -1462,6 +1932,7 @@ void init_gmpf()
|
|
1462
1932
|
rb_define_singleton_method(cGMP_F, "new", r_gmpfsg_new, -1);
|
1463
1933
|
rb_define_method(cGMP_F, "initialize", r_gmpf_initialize, -1);
|
1464
1934
|
#ifdef MPFR
|
1935
|
+
rb_define_singleton_method(cGMP_F, "new_2exp", r_gmpfsg_new_2exp, -1);
|
1465
1936
|
rb_define_singleton_method(cGMP_F, "nan", r_gmpfsg_nan, 0);
|
1466
1937
|
rb_define_singleton_method(cGMP_F, "inf", r_gmpfsg_inf, -1);
|
1467
1938
|
#if MPFR_VERSION_MAJOR>2
|
@@ -1472,6 +1943,17 @@ void init_gmpf()
|
|
1472
1943
|
rb_define_method(cGMP_F, "prec=", r_gmpf_set_prec, 1);
|
1473
1944
|
rb_define_method(cGMP_F, "prec_raw=", r_gmpf_set_prec_raw, 1);
|
1474
1945
|
|
1946
|
+
#ifdef MPFR
|
1947
|
+
rb_define_singleton_method(cGMP_F, "emin", r_gmpfrsg_get_emin, 0);
|
1948
|
+
rb_define_singleton_method(cGMP_F, "emax", r_gmpfrsg_get_emax, 0);
|
1949
|
+
rb_define_singleton_method(cGMP_F, "emin=", r_gmpfrsg_set_emin, 1);
|
1950
|
+
rb_define_singleton_method(cGMP_F, "emax=", r_gmpfrsg_set_emax, 1);
|
1951
|
+
rb_define_singleton_method(cGMP_F, "emin_min", r_gmpfrsg_get_emin_min, 0);
|
1952
|
+
rb_define_singleton_method(cGMP_F, "emin_max", r_gmpfrsg_get_emin_max, 0);
|
1953
|
+
rb_define_singleton_method(cGMP_F, "emax_min", r_gmpfrsg_get_emax_min, 0);
|
1954
|
+
rb_define_singleton_method(cGMP_F, "emax_max", r_gmpfrsg_get_emax_max, 0);
|
1955
|
+
#endif /* MPFR */
|
1956
|
+
|
1475
1957
|
// Converting Floats
|
1476
1958
|
rb_define_method(cGMP_F, "to_s", r_gmpf_to_s, -1);
|
1477
1959
|
rb_define_alias(cGMP_F, "inspect", "to_s");
|
@@ -1519,7 +2001,6 @@ void init_gmpf()
|
|
1519
2001
|
/* TODO: new in MPFR 3.0.0:
|
1520
2002
|
*
|
1521
2003
|
* mpfr_ai
|
1522
|
-
* mpfr_set_z_2exp
|
1523
2004
|
*/
|
1524
2005
|
|
1525
2006
|
/* TODO: new in MPFR 3.1.0:
|