gmp 0.4.7-x86-mingw32 → 0.5.3-x86-mingw32

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.
Files changed (56) hide show
  1. data/CHANGELOG +31 -0
  2. data/README.rdoc +16 -8
  3. data/benchmark/gexpr +0 -0
  4. data/benchmark/multiply +1 -1
  5. data/benchmark/multiply.gc +57 -0
  6. data/benchmark/pi +126 -0
  7. data/benchmark/srb.sh +21 -0
  8. data/ext/extconf.rb +3 -0
  9. data/ext/gmp.c +16 -7
  10. data/ext/gmp.so +0 -0
  11. data/ext/gmpbench_timing.c +1 -1
  12. data/ext/gmpf.c +445 -104
  13. data/ext/gmpq.c +25 -17
  14. data/ext/gmpz.c +232 -120
  15. data/ext/libmpfr-4.dll +0 -0
  16. data/ext/mprnd.c +23 -5
  17. data/ext/ruby_gmp.h +75 -9
  18. data/lib/gmp.rb +9 -0
  19. data/manual.pdf +0 -0
  20. data/manual.tex +494 -60
  21. data/test/README +1 -0
  22. data/test/mpfr_tcbrt.rb +95 -0
  23. data/test/mpfr_tisnan.rb +70 -0
  24. data/test/mpfr_trec_sqrt.rb +62 -0
  25. data/test/mpfr_tsqrt.rb +142 -6
  26. data/test/tc_cmp.rb +4 -4
  27. data/test/tc_constants.rb +10 -0
  28. data/test/tc_division.rb +13 -2
  29. data/test/tc_f_arithmetics_coersion.rb +2 -2
  30. data/test/tc_f_precision.rb +4 -3
  31. data/test/tc_fib_fac_nextprime.rb +2 -2
  32. data/test/tc_floor_ceil_truncate.rb +2 -2
  33. data/test/tc_hashes.rb +0 -2
  34. data/test/tc_logical_roots.rb +1 -3
  35. data/test/tc_mpfr_constants.rb +11 -0
  36. data/test/tc_mpfr_functions.rb +22 -9
  37. data/test/tc_mpfr_random.rb +1 -3
  38. data/test/tc_mpfr_rounding.rb +10 -7
  39. data/test/tc_q.rb +1 -3
  40. data/test/tc_q_basic.rb +3 -5
  41. data/test/tc_random.rb +1 -3
  42. data/test/tc_sgn_neg_abs.rb +1 -3
  43. data/test/tc_swap.rb +1 -3
  44. data/test/tc_z.rb +3 -3
  45. data/test/tc_z_addmul.rb +92 -0
  46. data/test/tc_z_basic.rb +6 -8
  47. data/test/tc_z_exponentiation.rb +1 -3
  48. data/test/tc_z_gcd_lcm_invert.rb +1 -3
  49. data/test/tc_z_jac_leg_rem.rb +1 -3
  50. data/test/tc_z_logic.rb +2 -2
  51. data/test/tc_z_shifts_last_bits.rb +2 -2
  52. data/test/tc_z_to_d_to_i.rb +2 -2
  53. data/test/test_helper.rb +1 -1
  54. data/test/test_unit/assertions.rb +31 -0
  55. data/test/unit_tests.rb +33 -27
  56. metadata +35 -8
data/CHANGELOG CHANGED
@@ -1,3 +1,34 @@
1
+ 0.5.3:
2
+ * Now supporting GMP 5.0.1 (I now test with GMP 4.3.2 and 5.0.1).
3
+ * Now supporting MPFR 3.0.0 (I now test with MPFR 2.4.2 and 3.0.0).
4
+ * Now supporting Ruby 1.9.2. A few changes had to be made.
5
+ * Added MPFR method GMP::F.zero? (mpfr_zero_p) with tests.
6
+ * Added MPFR method GMP::F.regular? (mpfr_regular_p) with tests (MPFR 3.0.0
7
+ only).
8
+ * Added MPFR methods GMP::F.rec_sqrt (mpfr_rec_sqrt) and GMP::F.cbrt
9
+ (mpfr_rec_cbrt), both heavily tested.
10
+ * Added MPFR method GMP::F.digamma (mpfr_digamma), not tested.
11
+ * Added GMP::F.prec= (mpf_set_prec) and GMP::F.prec_raw= (mpf_set_prec_raw),
12
+ neither tested yet.
13
+ * Added a dramatic amount of content to the manual. 26 pages.
14
+ * Unit test results: 98 tests, 11974 assertions, 0 failures, 0 errors
15
+ * Unit test results: 98 tests, 11961 assertions, 0 failures, 0 errors (MPFR 2.4.2)
16
+ * Unit test results: 79 tests, 742 assertions, 0 failures, 0 errors (w/o MPFR)
17
+
18
+ 0.4.19:
19
+ * Added FIX2NUM macro to help support x86_64.
20
+ * Fixed bug in MPRF functions; they were not using specified rounding modes.
21
+ * Added ** (pow) to GMP::F (when not using MPFR)
22
+ * Fixed add'l bug in MPFR functions, when specifying a rounding mode.
23
+ * Fixed memory bug when specifying an invalid precision, or base range.
24
+ * Fixed GMP::Z#pow (note that GMP::Z.pow has always worked.)
25
+ * Added many tests from MPFR's tsqrt.c. This actually exposed a lot of bugs in
26
+ the gem.
27
+ * Added GMP::Z.size (mpz_size). Not tested yet.
28
+ * Added GMP::Z.addmul! (mpz_addmul) with tests.
29
+ * Unit test results: 90 tests, 1500 assertions, 0 failures, 0 errors
30
+ * Unit test results: 79 tests, 742 assertions, 0 failures, 0 errors (w/o MPFR)
31
+
1
32
  0.4.7:
2
33
  * Added 6 MPFR trig methods, plus eint, li2, gamma, lngamma, zeta, erf, erfc,
3
34
  j0, j1, jn, y0, y1, and yn.
data/README.rdoc CHANGED
@@ -87,6 +87,12 @@ as pi, are defined under class methods of GMP::F, listed below.
87
87
  GMP::GMP_RNDZ #=> The constant representing "round toward zero"
88
88
  GMP::GMP_RNDU #=> The constant representing "round toward plus infinity"
89
89
  GMP::GMP_RNDD #=> The constant representing "round toward minus infinity"
90
+ New in MPFR 3.0.0:
91
+ GMP::MPFR_RNDN
92
+ GMP::MPFR_RNDZ
93
+ GMP::MPFR_RNDU
94
+ GMP::MPFR_RNDD
95
+ GMP::MPFR_RNDA #=> The constant representing "round away from zero"
90
96
 
91
97
  =Classes
92
98
 
@@ -192,6 +198,7 @@ You can also call them as:
192
198
  popcount the number of bits equal to 1
193
199
  sizeinbase(b) digits in base b
194
200
  size_in_bin digits in binary
201
+ size number of limbs
195
202
  to_i convert to Fixnum or Bignum
196
203
  GMP::Q and GMP::F
197
204
  / division
@@ -226,6 +233,8 @@ You can also call them as:
226
233
  const_catalan returns catalan
227
234
  GMP::F
228
235
  sqrt square root of the object
236
+ rec_sqrt square root of the recprical of the object
237
+ cbrt cube root of the object
229
238
  ** power
230
239
  log natural logarithm of object
231
240
  log2 binary logarithm of object
@@ -241,6 +250,7 @@ You can also call them as:
241
250
  li2 real part of the dilogarithm of object
242
251
  gamma Gamma fucntion of object
243
252
  lngamma logarithm of the Gamma function of object
253
+ digamma Digamma function of object (MPFR_VERSION >= "3.0.0")
244
254
  zeta Reimann Zeta function of object
245
255
  erf error function of object
246
256
  erfc complementary error function of object
@@ -265,13 +275,14 @@ You can also call them as:
265
275
  sec |
266
276
  csc |
267
277
  cot |
268
- aconh |
278
+ acosh |
269
279
  asinh |
270
280
  atanh /
271
281
  nan? \
272
282
  infinite? | type of floating point number
273
283
  finite? |
274
- number? /
284
+ number? |
285
+ regular? / (MPFR_VERSION >= "3.0.0")
275
286
  GMP::RandState
276
287
  mpfr_urandomb(fixnum) get uniformly distributed random floating-point
277
288
  number within 0 <= rop < 1
@@ -290,8 +301,6 @@ that is fixed with the unit_test gem.
290
301
 
291
302
  =Known Issues
292
303
 
293
- * GMP::Z#pow does not appear to be working at all. Looking at the code, I don't
294
- think it ever did.
295
304
  * Don't call GMP::RandState(:lc_2exp_size). Give a 2nd arg.
296
305
 
297
306
  =Precision
@@ -380,11 +389,10 @@ efficiency in GMP; the inefficiencies of the gmp gem are relatively greater.
380
389
  =Todo
381
390
 
382
391
  These are inherited from Tomasz. I will go through these and see which are
383
- still relevant.
392
+ still relevant, and which I understand.
384
393
 
385
394
  * mpz_fits_* and 31 vs. 32 integer variables
386
395
  * fix all sign issues (don't know what these are)
387
- * floats with precision control
388
396
  * to_s vs. inspect
389
397
  * check if mpz_addmul_ui would optimize some statements
390
398
  * some system that allows using denref and numref as normal ruby objects (?)
@@ -404,5 +412,5 @@ still relevant.
404
412
  * check if different sorting of operatations gives better cache usage
405
413
  * GMP::* op RubyFloat and RubyFloat op GMP::*
406
414
  * sort checks
407
- * GMP::Q.to_s(base), GMP::F.to_s(base)
408
- * benchmark gcdext, pi
415
+ * GMP::Q.to_s(base), GMP::F.to_s(base) (test it!)
416
+ * benchmark gcdext, pi
data/benchmark/gexpr ADDED
Binary file
data/benchmark/multiply CHANGED
@@ -41,4 +41,4 @@ while true
41
41
  f = f * 0.1
42
42
  end
43
43
 
44
- puts "RESULT: %#{decimals}f operations per second\n" % ops_per_sec
44
+ puts "RESULT: %#{decimals}f operations per second\n" % ops_per_sec
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require '../ext/gmp'
4
+
5
+ multiplicands = ARGV
6
+ random_state = GMP::RandState.new
7
+
8
+ if multiplicands.size > 1
9
+ m, n = multiplicands[0].to_i, multiplicands[1].to_i
10
+ x = random_state.urandomb(m)
11
+ y = random_state.urandomb(n)
12
+ else
13
+ m = multiplicands[0].to_i
14
+ x = random_state.urandomb(m)
15
+ y = x
16
+ end
17
+
18
+ t = GMP::time { z = x * y }
19
+ iterations = (1 + (1e4 / t)).to_i
20
+
21
+ if multiplicands.size > 1
22
+ print "Multiplying %i-bit number with %i-bit number %i times..." % [m, n, iterations]
23
+ else
24
+ print "Squaring a %i-bit number %i times..." % [m, iterations]
25
+ end
26
+ STDOUT.flush
27
+
28
+ t0 = GMP::cputime
29
+ #iterations.times do
30
+ # z = x * y
31
+ #end
32
+ parts = 512
33
+ foo = iterations / parts
34
+ bar = iterations % parts
35
+ foo.times do
36
+ parts.times do
37
+ z = x * y
38
+ end
39
+ GC.start
40
+ end
41
+ bar.times do
42
+ z = x * y
43
+ end
44
+
45
+ ti = GMP::cputime - t0
46
+
47
+ puts "done!"
48
+ ops_per_sec = 1000.0 * iterations / ti
49
+ f = 100.0
50
+ decimals = 0
51
+ while true
52
+ decimals += 1
53
+ break if ops_per_sec > f
54
+ f = f * 0.1
55
+ end
56
+
57
+ puts "RESULT: %#{decimals}f operations per second\n" % ops_per_sec
data/benchmark/pi ADDED
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require '../ext/gmp'
4
+
5
+ A = 13591409
6
+ B = 545140134
7
+ C = 640320
8
+ D = 12
9
+
10
+ BITS_PER_DIGIT = 3.32192809488736234787
11
+ DIGITS_PER_ITER = 14.1816474627254776555
12
+ DOUBLE_PREC = 53
13
+ INIT_FACS = 32
14
+
15
+ def my_sqrt_ui(r, x)
16
+ prec0 = r.prec
17
+ if prec0 < DOUBLE_PREC
18
+ r = GMP::F(Math.sqrt(x))
19
+ return
20
+ end
21
+
22
+ bits = 0
23
+ prec = prec0
24
+ while prec > DOUBLE_PREC
25
+ bit = prec & 1
26
+ prec = (prec+bit)/2
27
+ bits = bits*2 + bit
28
+ end
29
+
30
+ @t1.prec_raw=DOUBLE_PREC
31
+ @t1 = GMP::F(1/Math.sqrt(x))
32
+
33
+ while prec < prec0
34
+ prec *= 2
35
+ break if prec >= prec0
36
+ @t2.prec_raw=prec
37
+ @t2 = @t1 * @t1 # half x half -> full
38
+ @t2 *= x
39
+ @t2 = 1 - @t2
40
+ @t2.prec_raw=prec/2
41
+ @t2.div_2exp(@t2, 1)
42
+ @t2 *= @t1 # half x half -> half
43
+ @t1.prec_raw=prec
44
+ @t1 += @t2
45
+
46
+ prec -= bits & 1
47
+ bits /= 2
48
+ end
49
+
50
+ @t2.prec_raw=prec0/2
51
+ @t2 = @t1 * x
52
+ r = @t2 * @t2 # half * half -> full
53
+ r = x - r
54
+ @t1 *= r # half * half -> half
55
+ @t1.div_2exp(@t1, 1)
56
+ r = @t1+@t2
57
+ end
58
+
59
+ def my_div(r, y, x)
60
+ prec0 = r.prec
61
+ if prec0 <= DOUBLE_PREC
62
+ r = GMP::F(y.to_f / x.to_f)
63
+ return
64
+ end
65
+
66
+ bits = 0
67
+ prec = prec0
68
+ while prec > DOUBLE_PREC
69
+ bit = prec & 1
70
+ prec = (prec+bit)/2
71
+ bits = bits*2 + bit
72
+ end
73
+
74
+ @t1.prec_raw=DOUBLE_PREC
75
+ @t1 = 1 / x
76
+
77
+ while prec < prec0
78
+ prec *= 2
79
+ if prec < prec0
80
+ @t2.prec_raw=prec
81
+ @t2 = x * @t1 # full x half -> full
82
+ @t2 = 1 - @t2
83
+ @t2.prec_raw=prec/2
84
+ @t2 *= @t1 # half * half -> half
85
+ @t1.prec_raw=prec
86
+ @t1 += @t2
87
+ else
88
+ prec = prec0
89
+ @t2.prec_raw=prec/2
90
+ @t2 = @t1 * y # half * half -> half
91
+ r = x * @t2 # full * half -> full
92
+ r = y - r
93
+ t1 *= r # half * half -> half
94
+ r = t1 + t2
95
+ break
96
+ end
97
+
98
+ prec -= bits & 1
99
+ bits /= 2
100
+ end
101
+ end
102
+
103
+ def min(x,y); x < y ? x : y; end
104
+ def max(x,y); x > y ? x : y; end
105
+
106
+ Fac_t = Struct.new(max_facs, num_facs, fac, pow)
107
+ Sieve_t = Struct.new(fac, pow, nxt);
108
+
109
+ sieve = Sieve_t.new
110
+ ftmp = Fac_t.new
111
+ fmul = Fac_t.new
112
+
113
+ def fac_show(f)
114
+ (0...(f.num_facs)).each do |f|
115
+ if f.pow[i] == 1
116
+ print "#{f.fac[i]} "
117
+ else
118
+ print "#{f.fac[i]}^#{f.pow[i]} "
119
+ end
120
+ end
121
+ puts ""
122
+ end
123
+
124
+ def fac_reset(f)
125
+ f.num_facs = 0
126
+ end
data/benchmark/srb.sh ADDED
@@ -0,0 +1,21 @@
1
+ #! /bin/bash
2
+ source ~/.rvm/scripts/rvm
3
+
4
+ if [ $# -gt 0 ]; then
5
+ rvm use $1
6
+ if [ $? -ne 0 ]; then
7
+ echo "ERROR: rvm doesn't like \"$1\". Quitting."
8
+ exit 1
9
+ fi
10
+ fi
11
+
12
+ LIBS=-lgmp ./runbench -n
13
+ if [ $? -ne 0 ]; then
14
+ echo "ERROR: ruby extconf.rb didn't work so hot. Quitting."
15
+ exit 2
16
+ fi
17
+
18
+ echo "RUBY: `ruby -v`"
19
+ echo "GMP: `ruby -r '../lib/gmp' -e \"puts GMP::GMP_VERSION\"`"
20
+ echo "GMP_CC: `ruby -r '../lib/gmp' -e \"puts GMP::GMP_CC\"`"
21
+
data/ext/extconf.rb CHANGED
@@ -5,6 +5,7 @@ require 'mkmf'
5
5
  dir_config('gmp')
6
6
  dir_config('mpfr')
7
7
 
8
+ use_if_mpfr = ! ARGV.include?('--no-mpfr')
8
9
  ok = true
9
10
  unless have_header('gmp.h')
10
11
  $stderr.puts "can't find gmp.h, try --with-gmp-include=<path>"
@@ -16,11 +17,13 @@ unless have_library('gmp', '__gmpz_init')
16
17
  ok = false
17
18
  end
18
19
 
20
+ if use_if_mpfr
19
21
  if (have_header('mpfr.h') and
20
22
  have_header('mpf2mpfr.h') and
21
23
  have_library('mpfr', 'mpfr_init'))
22
24
  $CFLAGS += ' -DMPFR'
23
25
  end
26
+ end
24
27
 
25
28
  $CFLAGS += ' -Wall -W -O6 -g'
26
29
  if ok
data/ext/gmp.c CHANGED
@@ -13,7 +13,11 @@ VALUE cGMP_Rnd;
13
13
 
14
14
  void r_gmpz_free(void *ptr) { mpz_clear (ptr); free (ptr); }
15
15
  void r_gmpq_free(void *ptr) { mpq_clear (ptr); free (ptr); }
16
+ #ifdef MPFR
17
+ void r_gmpf_free(void *ptr) { mpfr_clear (ptr); free (ptr); }
18
+ #else
16
19
  void r_gmpf_free(void *ptr) { mpf_clear (ptr); free (ptr); }
20
+ #endif
17
21
  void r_gmprandstate_free(void *ptr) { gmp_randclear (ptr); free (ptr); }
18
22
 
19
23
  static void mpq_str_set(MP_RAT *ROP, char *str)
@@ -46,7 +50,7 @@ static VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
46
50
  mpq_get_struct(argv[0], arg_val);
47
51
  mpq_set (self_val, arg_val);
48
52
  } else if (argc == 1 && STRING_P(argv[0])) {
49
- mpq_str_set (self_val, STR2CSTR(argv[0]));
53
+ mpq_str_set (self_val, StringValuePtr(argv[0]));
50
54
  } else {
51
55
  mpz_set_value (mpq_numref(self_val), argv[0]);
52
56
  if (argc == 2) {
@@ -83,10 +87,10 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
83
87
  {
84
88
  (void)klass;
85
89
  if (FIXNUM_P(arg)) {
86
- if (FIX2INT(arg) <= 0) {
90
+ if (FIX2NUM(arg) <= 0) {
87
91
  rb_raise(rb_eRangeError, "prec must be positive");
88
92
  }
89
- mpf_set_default_prec (FIX2INT(arg));
93
+ mpf_set_default_prec (FIX2NUM(arg));
90
94
  } else {
91
95
  rb_raise(rb_eTypeError, "prec must be FixNum");
92
96
  }
@@ -133,6 +137,11 @@ static VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
133
137
  case 3:
134
138
  mpfr_set_default_rounding_mode (GMP_RNDD);
135
139
  break;
140
+ #if MPFR_VERSION_MAJOR>2
141
+ case 4:
142
+ mpfr_set_default_rounding_mode (MPFR_RNDA);
143
+ break;
144
+ #endif
136
145
  }
137
146
 
138
147
  return Qnil;
@@ -160,6 +169,10 @@ mp_rnd_t r_get_rounding_mode(VALUE rnd)
160
169
  return GMP_RNDU;
161
170
  case 3:
162
171
  return GMP_RNDD;
172
+ #if MPFR_VERSION_MAJOR>2
173
+ case 4:
174
+ return MPFR_RNDA;
175
+ #endif
163
176
  default:
164
177
  return GMP_RNDN;
165
178
  }
@@ -188,10 +201,6 @@ void Init_gmp() {
188
201
  rb_define_const(mGMP, "MPFR_VERSION", rb_str_new2(MPFR_VERSION_STRING));
189
202
  rb_define_const(mGMP, "MPFR_PREC_MIN", INT2FIX(MPFR_PREC_MIN));
190
203
  rb_define_const(mGMP, "MPFR_PREC_MAX", INT2FIX(MPFR_PREC_MAX));
191
- // rb_define_const(mGMP, "GMP_RNDN", INT2FIX(0));
192
- // rb_define_const(mGMP, "GMP_RNDZ", INT2FIX(1));
193
- // rb_define_const(mGMP, "GMP_RNDU", INT2FIX(2));
194
- // rb_define_const(mGMP, "GMP_RNDD", INT2FIX(3));
195
204
  #endif /* MPFR */
196
205
 
197
206
  cGMP_Z = rb_define_class_under(mGMP, "Z", rb_cInteger);
data/ext/gmp.so CHANGED
Binary file
@@ -41,7 +41,7 @@ cputime ()
41
41
  struct rusage rus;
42
42
 
43
43
  getrusage (0, &rus);
44
- return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
44
+ return (int) (rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000);
45
45
  }
46
46
  #endif
47
47
 
data/ext/gmpf.c CHANGED
@@ -72,8 +72,8 @@ VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass)
72
72
  VALUE res;
73
73
  (void)klass;
74
74
 
75
- if (argc > 2)
76
- rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1 or 2)", argc);
75
+ if (argc > 4)
76
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1 2, 3, or 4)", argc);
77
77
 
78
78
  mpf_make_struct (res, res_val);
79
79
  rb_obj_call_init(res, argc, argv);
@@ -90,30 +90,68 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
90
90
  mpf_get_struct (self, self_val);
91
91
 
92
92
  if (argc==0) {
93
- mpf_init(self_val);
94
- mpf_set_si(self_val, 0);
93
+ #ifdef MPFR
94
+ mpfr_init (self_val);
95
+ mpfr_set_si (self_val, 0, __gmp_default_rounding_mode);
96
+ #else
97
+ r_mpf_init (self_val);
98
+ mpf_set_si (self_val, 0);
99
+ #endif
95
100
  return Qnil;
96
101
  }
97
102
 
98
103
  arg = argv[0];
99
104
 
100
- if (argc == 2) {
105
+ //argc >= 2 ==> argv[0] is value, argv[1] is prec
106
+ if (argc >= 2) {
101
107
  if (FIXNUM_P(argv[1])) {
102
108
  if (FIX2INT(argv[1]) >= 0)
103
109
  prec = FIX2INT(argv[1]);
104
- else
110
+ else {
111
+ r_mpf_init (self_val);
105
112
  rb_raise(rb_eRangeError, "prec must be non-negative");
113
+ }
106
114
  } else {
115
+ r_mpf_init (self_val);
107
116
  rb_raise(rb_eTypeError, "prec must be a Fixnum");
108
117
  }
109
118
  } else if (GMPF_P(arg)) {
110
119
  mpf_get_struct (arg, arg_val_f);
111
120
  prec = mpf_get_prec (arg_val_f);
112
121
  }
122
+ #ifdef MPFR
123
+ int base = 10;
113
124
  if (prec == 0)
114
- mpf_init (self_val);
125
+ mpfr_init (self_val);
115
126
  else
116
- mpf_init2 (self_val, prec);
127
+ mpfr_init2 (self_val, prec);
128
+
129
+ if (STRING_P(argv[0])) {
130
+ if (argc >= 3) {
131
+ if (FIXNUM_P(argv[2])) {
132
+ if (FIX2INT(argv[2]) >= 2 && FIX2INT(argv[2]) <= 36)
133
+ base = FIX2INT(argv[2]);
134
+ else
135
+ rb_raise(rb_eRangeError, "base must be between 2 and 36");
136
+ }
137
+ else {
138
+ rb_raise(rb_eTypeError, "base must be a Fixnum");
139
+ }
140
+ }
141
+ if (argc == 4) {
142
+ // FIGURE IT OUT. ACCEPT A ROUNDING MODE!
143
+ }
144
+
145
+ mpf_set_value2 (self_val, arg, base);
146
+ return Qnil;
147
+ }
148
+
149
+ #else
150
+ if (prec == 0)
151
+ r_mpf_init (self_val);
152
+ else
153
+ r_mpf_init2 (self_val, prec);
154
+ #endif
117
155
 
118
156
  if (GMPF_P(arg)) {
119
157
  mpf_get_struct (arg, arg_val_f);
@@ -130,32 +168,71 @@ void mpf_set_value(MP_FLOAT *self_val, VALUE arg)
130
168
  {
131
169
  MP_RAT *arg_val_q;
132
170
  MP_INT *arg_val_z;
171
+ int result;
133
172
 
173
+ #ifdef MPFR
174
+ if (GMPQ_P(arg)) {
175
+ mpq_get_struct(arg, arg_val_q);
176
+ r_mpf_set_q(self_val, arg_val_q);
177
+ } else if (GMPZ_P(arg)) {
178
+ mpz_get_struct(arg, arg_val_z);
179
+ r_mpf_set_z(self_val, arg_val_z);
180
+ } else if (FLOAT_P(arg)) {
181
+ mpfr_set_d(self_val, NUM2DBL(arg), __gmp_default_rounding_mode);
182
+ } else if (FIXNUM_P(arg)) {
183
+ mpf_set_si(self_val, FIX2NUM(arg));
184
+ } else if (STRING_P(arg)) {
185
+ result = mpfr_set_str(self_val, StringValuePtr(arg), 10, __gmp_default_rounding_mode);
186
+ if (result == -1) {
187
+ rb_raise(rb_eRuntimeError, "Badly formatted string");
188
+ }
189
+ } else if (BIGNUM_P(arg)) {
190
+ #if 1 /* GMP3 code */
191
+ mpz_temp_from_bignum(arg_val_z, arg);
192
+ r_mpf_set_z(self_val, arg_val_z);
193
+ mpz_temp_free(arg_val_z);
194
+ #endif
195
+ #else
134
196
  if (GMPQ_P(arg)) {
135
197
  mpq_get_struct(arg, arg_val_q);
136
- mpf_set_q(self_val, arg_val_q);
198
+ r_mpf_set_q(self_val, arg_val_q);
137
199
  } else if (GMPZ_P(arg)) {
138
200
  mpz_get_struct(arg, arg_val_z);
139
- mpf_set_z(self_val, arg_val_z);
201
+ r_mpf_set_z(self_val, arg_val_z);
140
202
  } else if (FLOAT_P(arg)) {
141
- mpf_set_d(self_val, NUM2DBL(arg));
203
+ r_mpf_set_d(self_val, NUM2DBL(arg));
142
204
  } else if (FIXNUM_P(arg)) {
143
- mpf_set_si(self_val, FIX2INT(arg));
205
+ mpf_set_si(self_val, FIX2NUM(arg));
144
206
  } else if (STRING_P(arg)) {
145
- if (mpf_set_str(self_val, STR2CSTR(arg), 10) == -1) {
207
+ result = r_mpf_set_str(self_val, StringValuePtr(arg), 10);
208
+ if (result == -1) {
146
209
  rb_raise(rb_eRuntimeError, "Badly formatted string");
147
210
  }
148
211
  } else if (BIGNUM_P(arg)) {
149
212
  #if 1 /* GMP3 code */
150
213
  mpz_temp_from_bignum(arg_val_z, arg);
151
- mpf_set_z(self_val, arg_val_z);
214
+ r_mpf_set_z(self_val, arg_val_z);
152
215
  mpz_temp_free(arg_val_z);
216
+ #endif
153
217
  #endif
154
218
  } else {
155
219
  rb_raise(rb_eTypeError, "Don't know how to convert %s into GMP::F", rb_class2name(rb_class_of(arg)));
156
220
  }
157
221
  }
158
222
 
223
+ #ifdef MPFR
224
+ void mpf_set_value2(MP_FLOAT *self_val, VALUE arg, int base)
225
+ {
226
+ int result;
227
+
228
+ result = mpfr_set_str(self_val, StringValuePtr(arg), base, __gmp_default_rounding_mode);
229
+
230
+ if (result == -1) {
231
+ rb_raise(rb_eRuntimeError, "Badly formatted string");
232
+ }
233
+ }
234
+ #endif
235
+
159
236
  /*
160
237
  * call-seq:
161
238
  * GMP::F(arg)
@@ -181,6 +258,48 @@ VALUE r_gmpf_to_d(VALUE self)
181
258
  return rb_float_new(mpf_get_d(self_val));
182
259
  }
183
260
 
261
+ #ifdef MPFR
262
+ /*
263
+ * Document-method: to_s
264
+ *
265
+ * call-seq:
266
+ * float.to_s
267
+ *
268
+ * Returns the decimal representation of +float+, as a string.
269
+ */
270
+ VALUE r_gmpf_to_s(VALUE self)
271
+ {
272
+ MP_FLOAT *self_val;
273
+ char *str, *str2;
274
+ VALUE res;
275
+ mp_exp_t exponent;
276
+
277
+ mpf_get_struct(self, self_val);
278
+
279
+ //mpfr_sprintf(str, "%Rf", self_val);
280
+ //res = rb_str_new2(str);
281
+
282
+ str = mpfr_get_str(NULL, &exponent, 10, 0, self_val, __gmp_default_rounding_mode);
283
+ if ((strcmp(str, "NaN") == 0) ||
284
+ (strcmp(str, "Inf") == 0) ||
285
+ (strcmp(str, "-Inf") == 0))
286
+ {
287
+ res = rb_str_new2(str);
288
+ }
289
+ else
290
+ {
291
+ if (str[0] == '-')
292
+ __gmp_asprintf(&str2, "-0.%se%+ld", str+1, exponent);
293
+ else
294
+ __gmp_asprintf(&str2, "0.%se%+ld", str, exponent);
295
+ res = rb_str_new2(str2);
296
+ mpfr_free_str(str2);
297
+ }
298
+
299
+ mpfr_free_str(str);
300
+ return res;
301
+ }
302
+ #else
184
303
  /*
185
304
  * Document-method: to_s
186
305
  *
@@ -217,12 +336,14 @@ VALUE r_gmpf_to_s(VALUE self)
217
336
  free(str);
218
337
  return res;
219
338
  }
339
+ #endif
220
340
 
221
341
 
222
342
  /**********************************************************************
223
343
  * Float Arithmetic *
224
344
  **********************************************************************/
225
345
 
346
+ #ifndef MPFR
226
347
  /*
227
348
  * call-seq:
228
349
  * float + other
@@ -241,7 +362,7 @@ VALUE r_gmpf_add(VALUE self, VALUE arg)
241
362
  MP_RAT *arg_val_q;
242
363
  MP_INT *arg_val_z;
243
364
  VALUE res;
244
- unsigned long prec;
365
+ mpfr_prec_t prec;
245
366
 
246
367
  mpf_get_struct_prec (self, self_val, prec);
247
368
 
@@ -266,7 +387,7 @@ VALUE r_gmpf_add(VALUE self, VALUE arg)
266
387
  mpf_add (res_val, res_val, self_val);
267
388
  } else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
268
389
  mpf_make_struct_init(res, res_val, prec);
269
- mpf_set_si (res_val, FIX2INT(arg));
390
+ mpf_set_si (res_val, FIX2NUM(arg));
270
391
  mpf_add (res_val, res_val, self_val);
271
392
  } else if (BIGNUM_P(arg)) {
272
393
  mpz_temp_from_bignum(arg_val_z, arg);
@@ -280,6 +401,72 @@ VALUE r_gmpf_add(VALUE self, VALUE arg)
280
401
 
281
402
  return res;
282
403
  }
404
+ #else
405
+ /*
406
+ * call-seq:
407
+ * float + other
408
+ *
409
+ * Returns the sum of +float+ and +other+. +other+ can be
410
+ * * GMP::Z
411
+ * * Fixnum
412
+ * * GMP::Q
413
+ * * GMP::F
414
+ * * Bignum
415
+ * * Float
416
+ */
417
+ #define DEFUN_F_ZQXFBD2F(fname) \
418
+ VALUE r_gmpfr_##fname(int argc, VALUE *argv, VALUE self) \
419
+ { \
420
+ MP_FLOAT *self_val, *res_val, *arg_val_f; \
421
+ MP_RAT *arg_val_q; \
422
+ MP_INT *arg_val_z; \
423
+ VALUE arg, res, res_prec, rnd_mode; \
424
+ mpfr_prec_t prec, res_prec_val; \
425
+ mp_rnd_t rnd_mode_val; \
426
+ \
427
+ rb_scan_args (argc, argv, "12", &arg, &rnd_mode, &res_prec); \
428
+ \
429
+ mpf_get_struct_prec (self, self_val, prec); \
430
+ if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
431
+ else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
432
+ if (NIL_P (res_prec)) { res_prec_val = prec; } \
433
+ else { res_prec_val = FIX2INT (res_prec); } \
434
+ mpf_make_struct_init (res, res_val, res_prec_val); \
435
+ \
436
+ if (GMPF_P (arg)) { \
437
+ mpf_get_struct (arg, arg_val_f); \
438
+ prec_max (prec, arg_val_f); \
439
+ mpf_make_struct_init (res, res_val, prec); \
440
+ mpfr_##fname (res_val, self_val, arg_val_f, rnd_mode_val); \
441
+ } else if (GMPQ_P (arg)) { \
442
+ mpq_get_struct (arg, arg_val_q); \
443
+ mpf_make_struct_init (res, res_val, prec); \
444
+ mpfr_##fname##_q (res_val, self_val, arg_val_q, rnd_mode_val); \
445
+ } else if (GMPZ_P (arg)) { \
446
+ mpz_get_struct (arg, arg_val_z); \
447
+ mpf_make_struct_init (res, res_val, prec); \
448
+ mpfr_##fname##_z (res_val, self_val, arg_val_z, rnd_mode_val); \
449
+ } else if (FLOAT_P (arg)) { \
450
+ mpf_make_struct_init (res, res_val, prec); \
451
+ mpfr_##fname##_d (res_val, self_val, NUM2DBL (arg), rnd_mode_val); \
452
+ } else if (FIXNUM_P (arg)) { \
453
+ mpf_make_struct_init(res, res_val, prec); \
454
+ mpfr_##fname##_si (res_val, self_val, FIX2NUM (arg), rnd_mode_val); \
455
+ } else if (BIGNUM_P (arg)) { \
456
+ mpz_temp_from_bignum(arg_val_z, arg); \
457
+ mpf_make_struct_init(res, res_val, prec); \
458
+ mpfr_##fname##_z (res_val, self_val, arg_val_z, rnd_mode_val); \
459
+ mpz_temp_free (arg_val_z); \
460
+ } else { \
461
+ typeerror(ZQFXBD); \
462
+ } \
463
+ \
464
+ return res; \
465
+ }
466
+
467
+ DEFUN_F_ZQXFBD2F(add)
468
+ DEFUN_F_ZQXFBD2F(mul)
469
+ #endif
283
470
 
284
471
  /*
285
472
  * call-seq:
@@ -299,7 +486,7 @@ VALUE r_gmpf_sub(VALUE self, VALUE arg)
299
486
  MP_RAT *arg_val_q;
300
487
  MP_INT *arg_val_z;
301
488
  VALUE res;
302
- unsigned long prec;
489
+ mpfr_prec_t prec;
303
490
 
304
491
  mpf_get_struct_prec (self, self_val, prec);
305
492
 
@@ -324,7 +511,7 @@ VALUE r_gmpf_sub(VALUE self, VALUE arg)
324
511
  mpf_sub(res_val, self_val, res_val);
325
512
  } else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
326
513
  mpf_make_struct_init(res, res_val, prec);
327
- mpf_set_si(res_val, FIX2INT(arg));
514
+ mpf_set_si(res_val, FIX2NUM(arg));
328
515
  mpf_sub(res_val, self_val, res_val);
329
516
  } else if (BIGNUM_P(arg)) {
330
517
  mpz_temp_from_bignum(arg_val_z, arg);
@@ -357,7 +544,8 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
357
544
  MP_RAT *arg_val_q;
358
545
  MP_INT *arg_val_z;
359
546
  VALUE res;
360
- unsigned long prec;
547
+ //unsigned long prec;
548
+ mpfr_prec_t prec;
361
549
 
362
550
  mpf_get_struct_prec (self, self_val, prec);
363
551
 
@@ -382,7 +570,7 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
382
570
  mpf_mul(res_val, self_val, res_val);
383
571
  } else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
384
572
  mpf_make_struct_init(res, res_val, prec);
385
- mpf_set_si(res_val, FIX2INT(arg));
573
+ mpf_set_si(res_val, FIX2NUM(arg));
386
574
  mpf_mul(res_val, self_val, res_val);
387
575
  } else if (BIGNUM_P(arg)) {
388
576
  mpz_temp_from_bignum(arg_val_z, arg);
@@ -397,6 +585,92 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
397
585
  return res;
398
586
  }
399
587
 
588
+ /*
589
+ * call-seq:
590
+ * float ** integer
591
+ *
592
+ * Returns +float+ raised to the +integer+ power. +integer+ must be
593
+ * * Fixnum or Bignum
594
+ * * non-negative
595
+ */
596
+ VALUE r_gmpf_pow(VALUE self, VALUE arg)
597
+ {
598
+ MP_FLOAT *self_val, *res_val;
599
+ VALUE res;
600
+
601
+ //unsigned long prec;
602
+ mpfr_prec_t prec;
603
+
604
+ mpf_get_struct_prec (self, self_val, prec);
605
+
606
+ if (FIXNUM_P(arg)) {
607
+ if (FIX2NUM(arg) >= 0) {
608
+ mpf_make_struct_init(res, res_val, prec);
609
+ mpf_pow_ui(res_val, self_val, FIX2NUM(arg));
610
+ } else {
611
+ rb_raise(rb_eRangeError, "power must be non-negative");
612
+ }
613
+ } else {
614
+ typeerror(X);
615
+ }
616
+
617
+ return res;
618
+ }
619
+
620
+ #ifdef MPFR
621
+ /*
622
+ * call-seq:
623
+ * float ** other
624
+ *
625
+ * Returns +float+ raised to the +other+ power. +other+ must be an instance of
626
+ * * Fixnum
627
+ * * Bignum
628
+ * * Float
629
+ * * GMP::Z
630
+ * * GMP::F
631
+ */
632
+ /*VALUE r_gmpfr_pow(int argc, VALUE *argv, VALUE self)
633
+ {
634
+ MP_FLOAT *self_val, *res_val, *arg_val_f;
635
+ VALUE arg, rnd_mode, res_prec;
636
+ unsigned long arg_val, prec, res_prec_value;
637
+ mp_rnd_t rnd_mode_value;
638
+ MP_INT *arg_val_z;
639
+ VALUE res;
640
+
641
+ rb_scan_args (argc, argv, "12", &arg, &rnd_mode, &res_prec);
642
+
643
+ mpf_get_struct_prec (self, self_val, prec);
644
+
645
+ if (NIL_P (rnd_mode)) { rnd_mode_value = __gmp_default_rounding_mode; }
646
+ else { rnd_mode_value = r_get_rounding_mode(rnd_mode); }
647
+ if (NIL_P (res_prec)) { res_prec_value = prec; }
648
+ else { res_prec_value = FIX2INT (res_prec); }
649
+ mpf_make_struct_init (res, res_val, res_prec_value);
650
+
651
+ if (FIXNUM_P(arg)) {
652
+ mpfr_pow_ui(res_val, self_val, FIX2NUM(arg), rnd_mode_value);
653
+ } else if (BIGNUM_P(arg)) {
654
+ mpz_temp_from_bignum(arg_val_z, arg);
655
+ mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
656
+ mpz_temp_free(arg_val_z);
657
+ } else if (FLOAT_P(arg)) {
658
+ r_mpf_set_d (res_val, NUM2DBL(arg));
659
+ mpfr_pow (res_val, self_val, res_val, rnd_mode_value);
660
+ } else if (GMPZ_P(arg)) {
661
+ mpz_get_struct (arg, arg_val_z);
662
+ mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
663
+ } else if (GMPF_P(arg)) {
664
+ mpf_get_struct (arg, arg_val_f);
665
+ mpfr_pow (res_val, self_val, arg_val_f, rnd_mode_value);
666
+ } else {
667
+ typeerror(ZFXBD);
668
+ }
669
+
670
+ return res;
671
+ }*/
672
+ #endif
673
+
400
674
  /*
401
675
  * call-seq:
402
676
  * float1 / float2
@@ -415,7 +689,7 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
415
689
  MP_RAT *arg_val_q;
416
690
  MP_INT *arg_val_z;
417
691
  VALUE res;
418
- unsigned long prec;
692
+ mpfr_prec_t prec;
419
693
 
420
694
  mpf_get_struct_prec (self, self_val, prec);
421
695
 
@@ -440,7 +714,7 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
440
714
  mpf_div(res_val, self_val, res_val);
441
715
  } else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
442
716
  mpf_make_struct_init(res, res_val, prec);
443
- mpf_set_si(res_val, FIX2INT(arg));
717
+ mpf_set_si(res_val, FIX2NUM(arg));
444
718
  mpf_div(res_val, self_val, res_val);
445
719
  } else if (BIGNUM_P(arg)) {
446
720
  mpz_temp_from_bignum(arg_val_z, arg);
@@ -455,6 +729,8 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
455
729
  return res;
456
730
  }
457
731
 
732
+
733
+
458
734
  /*
459
735
  * Document-method: neg
460
736
  *
@@ -507,11 +783,11 @@ int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
507
783
 
508
784
  if (GMPF_P(arg)) {
509
785
  mpf_get_struct(arg,arg_val);
510
- return mpf_cmp (self_val, arg_val);
786
+ return r_mpf_cmp (self_val, arg_val);
511
787
  } else {
512
788
  mpf_temp_init(arg_val, mpf_get_prec (self_val));
513
789
  mpf_set_value (arg_val, arg);
514
- result = mpf_cmp (self_val, arg_val);
790
+ result = r_mpf_cmp (self_val, arg_val);
515
791
  mpf_temp_free(arg_val);
516
792
  return result;
517
793
  }
@@ -529,8 +805,8 @@ VALUE r_gmpf_cmp(VALUE self, VALUE arg)
529
805
  {
530
806
  MP_FLOAT *self_val;
531
807
  int res;
532
- mpf_get_struct(self,self_val);
533
- res = mpf_cmp_value(self_val, arg);
808
+ mpf_get_struct (self, self_val);
809
+ res = mpf_cmp_value (self_val, arg);
534
810
  if (res > 0)
535
811
  return INT2FIX(1);
536
812
  else if (res == 0)
@@ -547,26 +823,26 @@ DEFUN_FLOAT_CMP(ge,>=)
547
823
 
548
824
  #ifdef MPFR
549
825
 
550
- #define MPFR_SINGLE_FUNCTION(name) \
551
- VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
552
- { \
553
- MP_FLOAT *self_val, *res_val; \
554
- VALUE rnd_mode, res_prec; \
555
- unsigned long prec, res_prec_value; \
556
- mp_rnd_t rnd_mode_value; \
557
- VALUE res; \
558
- \
559
- rb_scan_args (argc, argv, "02", &rnd_mode, &res_prec); \
560
- \
561
- mpf_get_struct_prec (self, self_val, prec); \
562
- if (NIL_P (rnd_mode)) { rnd_mode_value = __gmp_default_rounding_mode; } \
563
- else { rnd_mode_value = r_get_rounding_mode(rnd_mode); } \
564
- if (NIL_P (res_prec)) { res_prec_value = prec; } \
565
- else { res_prec_value = FIX2INT (res_prec); } \
566
- mpf_make_struct_init (res, res_val, res_prec_value); \
567
- mpfr_##name (res_val, self_val, __gmp_default_rounding_mode); \
568
- \
569
- return res; \
826
+ #define MPFR_SINGLE_FUNCTION(name) \
827
+ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
828
+ { \
829
+ MP_FLOAT *self_val, *res_val; \
830
+ VALUE rnd_mode, res_prec; \
831
+ mpfr_prec_t prec, res_prec_value; \
832
+ mp_rnd_t rnd_mode_val; \
833
+ VALUE res; \
834
+ \
835
+ rb_scan_args (argc, argv, "02", &rnd_mode, &res_prec); \
836
+ \
837
+ mpf_get_struct_prec (self, self_val, prec); \
838
+ if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
839
+ else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
840
+ if (NIL_P (res_prec)) { res_prec_value = prec; } \
841
+ else { res_prec_value = FIX2INT (res_prec); } \
842
+ mpf_make_struct_init (res, res_val, res_prec_value); \
843
+ mpfr_##name (res_val, self_val, rnd_mode_val); \
844
+ \
845
+ return res; \
570
846
  }
571
847
 
572
848
  #define MPFR_SINGLE_1ARG_FUNCTION(name) \
@@ -574,7 +850,7 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
574
850
  { \
575
851
  MP_FLOAT *self_val, *res_val; \
576
852
  VALUE arg1, res_prec; \
577
- unsigned long prec, arg1_val, res_prec_value; \
853
+ mpfr_prec_t prec, arg1_val, res_prec_value; \
578
854
  VALUE res; \
579
855
  \
580
856
  rb_scan_args (argc, argv, "11", &arg1, &res_prec); \
@@ -590,6 +866,19 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
590
866
  return res; \
591
867
  }
592
868
 
869
+ #define MPFR_SINGLE_BOOLEAN_FUNCTION(name) \
870
+ static VALUE r_gmpfr_##name(VALUE self) \
871
+ { \
872
+ MP_FLOAT *self_val; \
873
+ \
874
+ mpf_get_struct(self, self_val); \
875
+ if (mpfr_##name (self_val)) \
876
+ return Qtrue; \
877
+ else \
878
+ return Qfalse; \
879
+ }
880
+
881
+
593
882
  #define MPFR_CONST_FUNCTION(name) \
594
883
  VALUE r_gmpfrsg_##name() \
595
884
  { \
@@ -604,6 +893,8 @@ VALUE r_gmpfrsg_##name() \
604
893
  }
605
894
 
606
895
  MPFR_SINGLE_FUNCTION(sqrt)
896
+ MPFR_SINGLE_FUNCTION(rec_sqrt)
897
+ MPFR_SINGLE_FUNCTION(cbrt)
607
898
 
608
899
  MPFR_SINGLE_FUNCTION(log)
609
900
  MPFR_SINGLE_FUNCTION(log2)
@@ -640,6 +931,9 @@ MPFR_SINGLE_FUNCTION(li2)
640
931
  MPFR_SINGLE_FUNCTION(gamma)
641
932
  MPFR_SINGLE_FUNCTION(lngamma)
642
933
  /*MPFR_SINGLE_FUNCTION(lgamma)*/
934
+ #if MPFR_VERSION_MAJOR > 2
935
+ MPFR_SINGLE_FUNCTION(digamma)
936
+ #endif
643
937
  MPFR_SINGLE_FUNCTION(zeta)
644
938
  MPFR_SINGLE_FUNCTION(erf)
645
939
  MPFR_SINGLE_FUNCTION(erfc)
@@ -655,32 +949,8 @@ MPFR_CONST_FUNCTION(const_pi)
655
949
  MPFR_CONST_FUNCTION(const_euler)
656
950
  MPFR_CONST_FUNCTION(const_catalan)
657
951
 
658
- static VALUE r_gmpfr_nan_p(VALUE self)
659
- {
660
- MP_FLOAT *self_val;
661
-
662
- mpf_get_struct(self, self_val);
663
- if (mpfr_nan_p(self_val)) {
664
- return Qtrue;
665
- }
666
- else {
667
- return Qfalse;
668
- }
669
- }
670
-
671
- static VALUE r_gmpfr_inf_p(VALUE self)
672
- {
673
- MP_FLOAT *self_val;
674
-
675
- mpf_get_struct(self, self_val);
676
- if (mpfr_inf_p(self_val)) {
677
- return Qtrue;
678
- }
679
- else {
680
- return Qfalse;
681
- }
682
- }
683
-
952
+ MPFR_SINGLE_BOOLEAN_FUNCTION(nan_p)
953
+ MPFR_SINGLE_BOOLEAN_FUNCTION(inf_p)
684
954
  static VALUE r_gmpfr_fin_p(VALUE self)
685
955
  {
686
956
  if (r_gmpfr_inf_p(self)) {
@@ -690,26 +960,18 @@ static VALUE r_gmpfr_fin_p(VALUE self)
690
960
  return Qtrue;
691
961
  }
692
962
  }
693
-
694
- static VALUE r_gmpfr_number_p(VALUE self)
695
- {
696
- MP_FLOAT *self_val;
697
-
698
- mpf_get_struct(self, self_val);
699
- if (mpfr_number_p(self_val)) {
700
- return Qtrue;
701
- }
702
- else {
703
- return Qfalse;
704
- }
705
- }
963
+ MPFR_SINGLE_BOOLEAN_FUNCTION(number_p)
964
+ MPFR_SINGLE_BOOLEAN_FUNCTION(zero_p)
965
+ #if MPFR_VERSION_MAJOR > 2
966
+ MPFR_SINGLE_BOOLEAN_FUNCTION(regular_p)
967
+ #endif
706
968
 
707
969
  static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
708
970
  {
709
971
  MP_FLOAT *self_val, *res_val, *arg_val_f;
710
972
  MP_RAT *arg_val_q;
711
973
  MP_INT *arg_val_z;
712
- unsigned long prec;
974
+ mpfr_prec_t prec;
713
975
  VALUE res;
714
976
 
715
977
  mpf_get_struct_prec(self, self_val, prec);
@@ -743,7 +1005,6 @@ static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
743
1005
  } else {
744
1006
  typeerror(ZQFXBD);
745
1007
  }
746
-
747
1008
  }
748
1009
 
749
1010
  return res;
@@ -771,15 +1032,39 @@ DEFUN_FLOAT2FLOAT(ceil,mpf_ceil)
771
1032
  VALUE r_gmpf_sgn(VALUE self)
772
1033
  {
773
1034
  MP_FLOAT *self_val;
774
- mpf_get_struct(self, self_val);
775
- return INT2FIX(mpf_sgn(self_val));
1035
+ mpf_get_struct (self, self_val);
1036
+ return INT2FIX (mpf_sgn (self_val));
776
1037
  }
777
1038
 
778
1039
  VALUE r_gmpf_get_prec(VALUE self)
779
1040
  {
780
1041
  MP_FLOAT *self_val;
781
- mpf_get_struct(self, self_val);
782
- return INT2NUM(mpf_get_prec(self_val));
1042
+ mpf_get_struct (self, self_val);
1043
+ return INT2NUM (mpf_get_prec (self_val));
1044
+ }
1045
+
1046
+ VALUE r_gmpf_set_prec(VALUE self, VALUE arg)
1047
+ {
1048
+ MP_FLOAT *self_val;
1049
+ if (FIXNUM_P(arg)) {
1050
+ mpf_get_struct (self, self_val);
1051
+ mpf_set_prec (self_val, FIX2NUM (arg));
1052
+ return Qnil;
1053
+ } else {
1054
+ typeerror(X);
1055
+ }
1056
+ }
1057
+
1058
+ VALUE r_gmpf_set_prec_raw(VALUE self, VALUE arg)
1059
+ {
1060
+ MP_FLOAT *self_val;
1061
+ if (FIXNUM_P(arg)) {
1062
+ mpf_get_struct (self, self_val);
1063
+ mpf_set_prec_raw (self_val, FIX2NUM (arg));
1064
+ return Qnil;
1065
+ } else {
1066
+ typeerror(X);
1067
+ }
783
1068
  }
784
1069
 
785
1070
 
@@ -794,6 +1079,9 @@ void init_gmpf()
794
1079
  // Initializing, Assigning Floats
795
1080
  rb_define_singleton_method(cGMP_F, "new", r_gmpfsg_new, -1);
796
1081
  rb_define_method(cGMP_F, "initialize", r_gmpf_initialize, -1);
1082
+ rb_define_method(cGMP_F, "prec", r_gmpf_get_prec, 0);
1083
+ rb_define_method(cGMP_F, "prec=", r_gmpf_set_prec, 1);
1084
+ rb_define_method(cGMP_F, "prec_raw=", r_gmpf_set_prec_raw, 1);
797
1085
 
798
1086
  // Converting Floats
799
1087
  rb_define_method(cGMP_F, "to_s", r_gmpf_to_s, 0);
@@ -801,10 +1089,18 @@ void init_gmpf()
801
1089
  rb_define_alias(cGMP_F, "to_f", "to_d");
802
1090
 
803
1091
  // Float Arithmetic
804
- rb_define_method(cGMP_F, "+", r_gmpf_add, 1);
805
1092
  rb_define_method(cGMP_F, "-", r_gmpf_sub, 1);
806
- rb_define_method(cGMP_F, "*", r_gmpf_mul, 1);
807
1093
  rb_define_method(cGMP_F, "/", r_gmpf_div, 1);
1094
+ #ifndef MPFR
1095
+ rb_define_method(cGMP_F, "+", r_gmpf_add, 1);
1096
+ rb_define_method(cGMP_F, "*", r_gmpf_mul, 1);
1097
+ rb_define_method(cGMP_F, "**", r_gmpf_pow, 1);
1098
+ rb_define_alias(cGMP_F, "pow", "**");
1099
+ #else
1100
+ rb_define_method(cGMP_F, "+", r_gmpfr_add, -1);
1101
+ rb_define_method(cGMP_F, "*", r_gmpfr_mul, -1);
1102
+ rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
1103
+ #endif
808
1104
  rb_define_method(cGMP_F, "-@", r_gmpf_neg, 0);
809
1105
  rb_define_method(cGMP_F, "neg!", r_gmpf_neg_self, 0);
810
1106
  rb_define_method(cGMP_F, "abs", r_gmpf_abs, 0);
@@ -817,18 +1113,53 @@ void init_gmpf()
817
1113
  rb_define_method(cGMP_F, "<", r_gmpf_cmp_lt, 1);
818
1114
  rb_define_method(cGMP_F, "<=", r_gmpf_cmp_le, 1);
819
1115
  rb_define_method(cGMP_F, "==", r_gmpf_eq, 1);
1116
+ rb_define_method(cGMP_F, "sgn", r_gmpf_sgn, 0);
1117
+
1118
+ // Miscellaneous Functions
1119
+ rb_define_method(cGMP_F, "ceil", r_gmpf_ceil, 0);
1120
+ rb_define_method(cGMP_F, "ceil!", r_gmpf_ceil_self, 0);
1121
+ rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
1122
+ rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);rb_define_method(cGMP_F, "trunc", r_gmpf_trunc, 0);
1123
+ rb_define_method(cGMP_F, "trunc!", r_gmpf_trunc_self, 0);
1124
+
820
1125
 
821
1126
  #ifdef MPFR
1127
+ /* To implement; new in MPFR 3.0.0:
1128
+ *
1129
+ * mpfr_buildopt_tls_p
1130
+ * mpfr_buildopt_decimal_p
1131
+ * mpfr_set_zero
1132
+ * mpfr_ai
1133
+ * mpfr_set_flt
1134
+ * mpfr_get_flt
1135
+ * mpfr_urandom
1136
+ * mpfr_set_z_2exp
1137
+ */
822
1138
  // Basic Arithmetic Functions
823
- rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, -1);
1139
+ rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, -1);
1140
+ rb_define_method(cGMP_F, "rec_sqrt", r_gmpfr_rec_sqrt, -1);
1141
+ rb_define_method(cGMP_F, "cbrt", r_gmpfr_cbrt, -1);
1142
+ // "root", r_gmpfr_root
1143
+ // "neg", r_gmpfr_neg
1144
+ // "abs", r_gmpfr_abs
1145
+ // "dim", r_gmpfr_dim
1146
+ // "mul_2", r_gmpfr_mul_2
1147
+ // "div_2", r_gmpfr_div_2
824
1148
 
825
- rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
1149
+ //rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
826
1150
 
827
1151
  // Comparison Functions
828
1152
  rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
829
1153
  rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
830
1154
  rb_define_method(cGMP_F, "finite?", r_gmpfr_fin_p, 0);
831
1155
  rb_define_method(cGMP_F, "number?", r_gmpfr_number_p, 0);
1156
+ rb_define_method(cGMP_F, "zero?", r_gmpfr_zero_p, 0);
1157
+ #if MPFR_VERSION_MAJOR > 2
1158
+ rb_define_method(cGMP_F, "regular?", r_gmpfr_regular_p, 0);
1159
+ #endif
1160
+ //"sgn", r_gmpfr_sgn
1161
+ //"lessgreater", r_gmpfr_lessgreater_p
1162
+ //"unordered", r_gmpfr_unordered_p
832
1163
 
833
1164
  // Special Functions
834
1165
  rb_define_method(cGMP_F, "log", r_gmpfr_log, -1);
@@ -840,6 +1171,7 @@ void init_gmpf()
840
1171
  rb_define_method(cGMP_F, "cos", r_gmpfr_cos, -1);
841
1172
  rb_define_method(cGMP_F, "sin", r_gmpfr_sin, -1);
842
1173
  rb_define_method(cGMP_F, "tan", r_gmpfr_tan, -1);
1174
+ // "sin_cos", r_gmpfr_sin_cos
843
1175
  rb_define_method(cGMP_F, "sec", r_gmpfr_sec, -1);
844
1176
  rb_define_method(cGMP_F, "csc", r_gmpfr_csc, -1);
845
1177
  rb_define_method(cGMP_F, "cot", r_gmpfr_cot, -1);
@@ -847,10 +1179,13 @@ void init_gmpf()
847
1179
  rb_define_method(cGMP_F, "acos", r_gmpfr_acos, -1);
848
1180
  rb_define_method(cGMP_F, "asin", r_gmpfr_asin, -1);
849
1181
  rb_define_method(cGMP_F, "atan", r_gmpfr_atan, -1);
1182
+ // "atan2", r_gmpfr_atan2
850
1183
 
851
1184
  rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, -1);
852
1185
  rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, -1);
853
1186
  rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, -1);
1187
+
1188
+ // "sinh_cosh", r_gmpfr_sinh_cosh
854
1189
 
855
1190
  rb_define_method(cGMP_F, "sech", r_gmpfr_sech, -1);
856
1191
  rb_define_method(cGMP_F, "csch", r_gmpfr_csch, -1);
@@ -859,6 +1194,8 @@ void init_gmpf()
859
1194
  rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, -1);
860
1195
  rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, -1);
861
1196
 
1197
+ // "fac", r_gmpfr_fac
1198
+
862
1199
  rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, -1);
863
1200
  rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, -1);
864
1201
  rb_define_method(cGMP_F, "eint", r_gmpfr_eint, -1);
@@ -866,6 +1203,9 @@ void init_gmpf()
866
1203
  rb_define_method(cGMP_F, "gamma", r_gmpfr_gamma, -1);
867
1204
  rb_define_method(cGMP_F, "lngamma", r_gmpfr_lngamma, -1);
868
1205
  /*rb_define_method(cGMP_F, "lgamma", r_gmpfr_lgamma, -1);*/
1206
+ #if MPFR_VERSION_MAJOR > 2
1207
+ rb_define_method(cGMP_F, "digamma", r_gmpfr_digamma, -1);
1208
+ #endif
869
1209
  rb_define_method(cGMP_F, "zeta", r_gmpfr_zeta, -1);
870
1210
  rb_define_method(cGMP_F, "erf", r_gmpfr_erf, -1);
871
1211
  rb_define_method(cGMP_F, "erfc", r_gmpfr_erfc, -1);
@@ -875,20 +1215,21 @@ void init_gmpf()
875
1215
  rb_define_method(cGMP_F, "y0", r_gmpfr_y0, -1);
876
1216
  rb_define_method(cGMP_F, "y1", r_gmpfr_y1, -1);
877
1217
  rb_define_method(cGMP_F, "yn", r_gmpfr_yn, -1);
1218
+
1219
+ // "fma", r_gmpfr_fma
1220
+ // "fms", r_gmpfr_fms
1221
+ // "agm", r_gmpfr_agm
1222
+ // "hypot", r_gmpfr_hypot
1223
+ // "ai", r_gmpfr_ai !! 3.0.0
878
1224
 
879
1225
  rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, 0);
880
1226
  rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, 0);
881
1227
  rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, 0);
882
1228
  rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan, 0);
1229
+
1230
+ // Integer and Remainder Related Functions
1231
+ // "integer?", r_gmpfr_integer_p
883
1232
  #endif /* MPFR */
884
1233
 
885
1234
  // _unsorted_
886
- rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
887
- rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);
888
- rb_define_method(cGMP_F, "ceil", r_gmpf_ceil, 0);
889
- rb_define_method(cGMP_F, "ceil!", r_gmpf_ceil_self, 0);
890
- rb_define_method(cGMP_F, "trunc", r_gmpf_trunc, 0);
891
- rb_define_method(cGMP_F, "trunc!", r_gmpf_trunc_self, 0);
892
- rb_define_method(cGMP_F, "sgn", r_gmpf_sgn, 0);
893
- rb_define_method(cGMP_F, "prec", r_gmpf_get_prec, 0);
894
1235
  }