gmp 0.6.47 → 0.7.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
[](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:
|