gmp 0.6.43 → 0.6.47

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