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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +21 -1
  3. data/README.markdown +29 -9
  4. data/ext/extconf.rb +8 -0
  5. data/ext/gmp.c +7 -7
  6. data/ext/gmpf.c +620 -139
  7. data/ext/gmpq.c +218 -90
  8. data/ext/gmprandstate.c +57 -53
  9. data/ext/gmpz.c +492 -440
  10. data/ext/mprnd.c +44 -35
  11. data/ext/ruby_gmp.h +6 -6
  12. data/manual.pdf +0 -0
  13. data/manual.tex +2 -2
  14. data/test/mpfr_thypot.rb +60 -0
  15. data/test/tc_cmp.rb +1 -1
  16. data/test/tc_constants.rb +1 -1
  17. data/test/tc_division.rb +1 -1
  18. data/test/tc_f_abs_neg.rb +1 -1
  19. data/test/tc_f_arithmetics_coersion.rb +1 -1
  20. data/test/tc_f_precision.rb +2 -1
  21. data/test/tc_f_to_s.rb +1 -1
  22. data/test/tc_hashes.rb +1 -4
  23. data/test/tc_mpfr_cmp.rb +1 -1
  24. data/test/tc_mpfr_constants.rb +1 -1
  25. data/test/tc_mpfr_functions.rb +43 -10
  26. data/test/tc_mpfr_inf_nan_zero.rb +1 -1
  27. data/test/tc_mpfr_integer.rb +1 -1
  28. data/test/tc_mpfr_new_rounding.rb +24 -1
  29. data/test/tc_mpfr_pow.rb +17 -0
  30. data/test/tc_mpfr_random.rb +1 -1
  31. data/test/tc_mpfr_rounding.rb +1 -1
  32. data/test/tc_q.rb +53 -32
  33. data/test/tc_q_basic.rb +1 -1
  34. data/test/{tc_floor_ceil_truncate.rb → tc_q_floor_ceil_truncate.rb} +2 -2
  35. data/test/tc_q_num_den.rb +18 -0
  36. data/test/tc_random.rb +1 -4
  37. data/test/tc_sgn_neg_abs.rb +1 -1
  38. data/test/tc_swap.rb +1 -1
  39. data/test/tc_z.rb +1 -1
  40. data/test/tc_z_addmul.rb +1 -1
  41. data/test/tc_z_basic.rb +3 -2
  42. data/test/tc_z_exponentiation.rb +5 -5
  43. data/test/tc_z_export_import.rb +1 -1
  44. data/test/{tc_fib_fac_nextprime.rb → tc_z_fib_fac_nextprime.rb} +1 -1
  45. data/test/tc_z_functional_mappings.rb +2 -2
  46. data/test/tc_z_gcd_lcm_invert.rb +1 -1
  47. data/test/tc_z_hamdist.rb +1 -1
  48. data/test/tc_z_io.rb +2 -1
  49. data/test/tc_z_jac_leg_rem.rb +1 -1
  50. data/test/tc_z_logic.rb +1 -1
  51. data/test/{tc_logical_roots.rb → tc_z_logical_roots.rb} +7 -7
  52. data/test/tc_z_shifts_last_bits.rb +2 -2
  53. data/test/tc_z_submul.rb +1 -1
  54. data/test/tc_z_to_dis.rb +1 -1
  55. data/test/{tc_zerodivisionexceptions.rb → tc_zero_division_exceptions.rb} +2 -2
  56. data/test/unit_tests.rb +30 -17
  57. metadata +16 -16
  58. data/INSTALL +0 -4
data/ext/gmpq.c CHANGED
@@ -7,9 +7,9 @@
7
7
  *
8
8
  * GMP Multiple Precision Rational Number.
9
9
  *
10
- * Instances of this class can store variables of the type mpq_t. This class also
11
- * contains many methods that act as the functions for mpq_t variables, as well as a few
12
- * methods that attempt to make this library more Ruby-ish.
10
+ * Instances of this class can store variables of the type `mpq_t`. This class
11
+ * also contains many methods that act as the functions for `mpq_t` variables,
12
+ * as well as a few methods that attempt to make this library more Ruby-ish.
13
13
  */
14
14
 
15
15
  /**********************************************************************
@@ -38,9 +38,9 @@ static VALUE r_gmpq_##fname(VALUE self) \
38
38
  }
39
39
 
40
40
  /*
41
- * DEFUN_RAT2RAT defines two functions. The first takes a GMP::Q as self, calls mpq_fname
42
- * on the contained mpq_t, whose arguments are exactly (0) the return argument and (1)
43
- * self. The second is the same destructive method.
41
+ * DEFUN_RAT2RAT defines two functions. The first takes a GMP::Q as self, calls
42
+ * mpq_fname on the contained mpq_t, whose arguments are exactly (0) the return
43
+ * argument and (1) self. The second is the same destructive method.
44
44
  */
45
45
  #define DEFUN_RAT2RAT(fname,mpq_fname) \
46
46
  static VALUE r_gmpq_##fname(VALUE self) \
@@ -82,7 +82,7 @@ VALUE r_gmpqsg_new(int argc, VALUE *argv, VALUE klass)
82
82
  (void)klass;
83
83
 
84
84
  if (argc > 2)
85
- rb_raise (rb_eArgError, "wrong # of arguments (%d for 0, 1 or 2)", argc);
85
+ rb_raise (rb_eArgError, "wrong number of arguments (%d for 0, 1 or 2)", argc);
86
86
 
87
87
  mpq_make_struct (res, res_val);
88
88
  mpq_init (res_val);
@@ -113,21 +113,45 @@ static void mpq_str_set(MP_RAT *ROP, char *str)
113
113
 
114
114
  VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
115
115
  {
116
- MP_RAT *self_val, *arg_val;
116
+ MP_RAT *self_val, *arg_val_q;
117
+ MP_INT *arg_z;
117
118
 
118
119
  if (argc != 0) {
119
120
  mpq_get_struct (self, self_val);
120
- if (argc == 1 && GMPQ_P (argv[0])) {
121
- mpq_get_struct (argv[0], arg_val);
122
- mpq_set (self_val, arg_val);
123
- } else if (argc == 1 && STRING_P (argv[0])) {
124
- mpq_str_set (self_val, StringValuePtr (argv[0]));
121
+ /* TODO: use mpq_set_f */
122
+ if (argc == 1) {
123
+ if (FIXNUM_P (argv[0])) {
124
+ if (FIX2NUM (argv[0]) >= 0)
125
+ mpq_set_ui (self_val, FIX2NUM (argv[0]), 1);
126
+ else
127
+ mpq_set_si (self_val, FIX2NUM (argv[0]), 1);
128
+ } else if (GMPZ_P (argv[0])) {
129
+ mpz_get_struct (argv[0], arg_z);
130
+ mpq_set_z (self_val, arg_z);
131
+ } else if (FLOAT_P (argv[0])) {
132
+ mpq_set_d (self_val, NUM2DBL (argv[0]));
133
+ } else if (GMPQ_P (argv[0])) {
134
+ mpq_get_struct (argv[0], arg_val_q);
135
+ mpq_set (self_val, arg_val_q);
136
+ } else if (STRING_P (argv[0])) {
137
+ mpq_str_set (self_val, StringValuePtr (argv[0]));
138
+ } else {
139
+ mpz_set_value (mpq_numref (self_val), argv[0], 0); /* are these segfaulting? */
140
+ }
141
+ } else if (argc == 2) {
142
+ if (FIXNUM_P (argv[0]) && FIXNUM_P (argv[1]) && FIX2NUM (argv[1]) >= 0) {
143
+ if (FIX2NUM (argv[0]) >= 0)
144
+ mpq_set_ui (self_val, FIX2NUM (argv[0]), FIX2NUM (argv[1]));
145
+ else
146
+ mpq_set_si (self_val, FIX2NUM (argv[0]), FIX2NUM (argv[1]));
147
+ } else {
148
+ mpz_set_value (mpq_numref (self_val), argv[0], 0); /* are these segfaulting? */
149
+ mpz_set_value (mpq_denref (self_val), argv[1], 0); /* are these segfaulting? */
150
+ }
151
+
152
+ mpq_canonicalize (self_val);
125
153
  } else {
126
- mpz_set_value (mpq_numref (self_val), argv[0], 0); // are these segfaulting?
127
- if (argc == 2) {
128
- mpz_set_value (mpq_denref (self_val), argv[1], 0); // are these segfaulting?
129
- mpq_canonicalize (self_val);
130
- } // AND IF ARGC != 2 ?!? WHAT JUST HAPPENED?
154
+ rb_raise (rb_eArgError, "wrong number of arguments (%d for 0, 1, or 2)", argc);
131
155
  }
132
156
  }
133
157
  return Qnil;
@@ -146,6 +170,7 @@ VALUE r_gmpmod_q(int argc, VALUE *argv, VALUE module)
146
170
  }
147
171
 
148
172
  /*
173
+ * Document-method: swap
149
174
  * call-seq:
150
175
  * p.swap(q)
151
176
  *
@@ -172,27 +197,30 @@ VALUE r_gmpq_swap (VALUE self, VALUE arg)
172
197
  **********************************************************************/
173
198
 
174
199
  /*
200
+ * Document-method: to_d
175
201
  * call-seq:
176
202
  * p.to_d
177
203
  *
178
204
  * Returns _p_ as an Float if _p_ fits in a Float.
179
205
  *
180
- * Otherwise returns the least significant part of _p_, with the same sign as _p_.
206
+ * Otherwise returns the least significant part of _p_, with the same sign as
207
+ * _p_.
181
208
  *
182
- * If the exponent from the conversion is too big or too small to fit a double then the
183
- * result is system dependent. For too big an infinity is returned when available. For
184
- * too small 0.0 is normally returned. Hardware overflow, underflow and denorm traps may
185
- * or may not occur.
209
+ * If the exponent from the conversion is too big or too small to fit a double
210
+ * then the result is system dependent. For too big an infinity is returned
211
+ * when available. For too small 0.0 is normally returned. Hardware overflow,
212
+ * underflow and denorm traps may or may not occur.
186
213
  */
187
214
  VALUE r_gmpq_to_d(VALUE self)
188
215
  {
189
216
  MP_RAT *self_val;
190
- mpq_get_struct(self, self_val);
217
+ mpq_get_struct (self, self_val);
191
218
 
192
- return rb_float_new(mpq_get_d(self_val));
219
+ return rb_float_new (mpq_get_d (self_val));
193
220
  }
194
221
 
195
222
  /*
223
+ * Document-method: to_s
196
224
  * call-seq:
197
225
  * p.to_s
198
226
  *
@@ -207,8 +235,7 @@ VALUE r_gmpq_to_s(VALUE self)
207
235
  size_t sizeinbase;
208
236
  size_t offset;
209
237
 
210
- //Data_Get_Struct (self, MP_RAT, self_val);
211
- mpq_get_struct(self, self_val)
238
+ mpq_get_struct (self, self_val)
212
239
 
213
240
  if (mpz_cmp_ui (mpq_denref (self_val), 1) == 0) {
214
241
  str = mpz_get_str (NULL, 10, mpq_numref (self_val));
@@ -227,7 +254,7 @@ VALUE r_gmpq_to_s(VALUE self)
227
254
  offset = strlen (str);
228
255
  str[offset] = '/';
229
256
  mpz_get_str (str + offset + 1, 10, self_val_den);
230
- res = rb_str_new2(str);
257
+ res = rb_str_new2 (str);
231
258
  free (str);
232
259
 
233
260
  return res;
@@ -239,10 +266,12 @@ VALUE r_gmpq_to_s(VALUE self)
239
266
  **********************************************************************/
240
267
 
241
268
  /*
269
+ * Document-method: +
242
270
  * call-seq:
243
271
  * p + q
244
272
  *
245
273
  * Adds _p_ to _q_. _q_ must be an instance of one of:
274
+ *
246
275
  * * GMP::Z
247
276
  * * Fixnum
248
277
  * * GMP::Q
@@ -255,46 +284,48 @@ VALUE r_gmpq_add(VALUE self, VALUE arg)
255
284
  MP_INT *arg_val_z, *res_val_num;
256
285
  VALUE res;
257
286
 
258
- mpq_get_struct(self, self_val);
259
- mpq_make_struct_init(res, res_val);
260
-
261
- if (GMPQ_P(arg)) {
262
- mpq_get_struct(arg,arg_val_q);
263
- mpq_add(res_val, self_val, arg_val_q);
264
- } else if (GMPZ_P(arg)) {
265
- res_val_num = mpq_numref(res_val);
266
- mpz_set(mpq_denref(res_val), mpq_denref(self_val));
267
- mpz_get_struct(arg, arg_val_z);
268
- mpz_mul(res_val_num, mpq_denref(self_val), arg_val_z);
269
- mpz_add(res_val_num, res_val_num, mpq_numref(self_val));
270
- } else if (FIXNUM_P(arg)) {
271
- res_val_num = mpq_numref(res_val);
272
- mpz_set(mpq_denref(res_val), mpq_denref(self_val));
273
- mpz_mul_si(res_val_num, mpq_denref(self_val), FIX2NUM(arg));
274
- mpz_add(res_val_num, res_val_num, mpq_numref(self_val));
275
- } else if (GMPF_P(arg)) {
287
+ mpq_get_struct (self, self_val);
288
+ mpq_make_struct_init (res, res_val);
289
+
290
+ if (GMPQ_P (arg)) {
291
+ mpq_get_struct (arg,arg_val_q);
292
+ mpq_add (res_val, self_val, arg_val_q);
293
+ } else if (GMPZ_P (arg)) {
294
+ res_val_num = mpq_numref (res_val);
295
+ mpz_set (mpq_denref (res_val), mpq_denref (self_val));
296
+ mpz_get_struct (arg, arg_val_z);
297
+ mpz_mul (res_val_num, mpq_denref (self_val), arg_val_z);
298
+ mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
299
+ } else if (FIXNUM_P (arg)) {
300
+ res_val_num = mpq_numref (res_val);
301
+ mpz_set (mpq_denref (res_val), mpq_denref (self_val));
302
+ mpz_mul_si (res_val_num, mpq_denref (self_val), FIX2NUM (arg));
303
+ mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
304
+ } else if (GMPF_P (arg)) {
276
305
  #ifndef MPFR
277
- return r_gmpf_add(arg,self);
306
+ return r_gmpf_add (arg,self);
278
307
  #else
279
- return rb_funcall(arg, rb_intern("+"), 1, self);
308
+ return rb_funcall (arg, rb_intern ("+"), 1, self);
280
309
  #endif
281
- } else if (BIGNUM_P(arg)) {
282
- res_val_num = mpq_numref(res_val);
283
- mpz_set(mpq_denref(res_val), mpq_denref(self_val));
284
- mpz_set_bignum(res_val_num, arg);
285
- mpz_mul(res_val_num, res_val_num, mpq_denref(self_val));
286
- mpz_add(res_val_num, res_val_num, mpq_numref(self_val));
310
+ } else if (BIGNUM_P (arg)) {
311
+ res_val_num = mpq_numref (res_val);
312
+ mpz_set (mpq_denref (res_val), mpq_denref (self_val));
313
+ mpz_set_bignum (res_val_num, arg);
314
+ mpz_mul (res_val_num, res_val_num, mpq_denref (self_val));
315
+ mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
287
316
  } else {
288
- typeerror(ZQFXB);
317
+ typeerror (ZQFXB);
289
318
  }
290
319
  return res;
291
320
  }
292
321
 
293
322
  /*
323
+ * Document-method: -
294
324
  * call-seq:
295
325
  * p - q
296
326
  *
297
327
  * Subtracts _p_ from _q_. _q_ must be an instance of one of:
328
+ *
298
329
  * * GMP::Z
299
330
  * * Fixnum
300
331
  * * GMP::Q
@@ -309,36 +340,36 @@ VALUE r_gmpq_sub(VALUE self, VALUE arg)
309
340
  VALUE res;
310
341
  mpfr_prec_t prec;
311
342
 
312
- mpq_get_struct(self, self_val);
313
- mpq_make_struct_init(res, res_val);
343
+ mpq_get_struct (self, self_val);
344
+ mpq_make_struct_init (res, res_val);
314
345
 
315
- if (GMPQ_P(arg)) {
316
- mpq_get_struct(arg,arg_val_q);
346
+ if (GMPQ_P (arg)) {
347
+ mpq_get_struct (arg,arg_val_q);
317
348
  mpq_sub (res_val, self_val, arg_val_q);
318
- } else if (GMPZ_P(arg)) {
319
- res_val_num = mpq_numref(res_val);
320
- mpz_set (mpq_denref(res_val), mpq_denref(self_val));
321
- mpz_get_struct(arg, arg_val_z);
322
- mpz_mul (res_val_num, mpq_denref(self_val), arg_val_z);
349
+ } else if (GMPZ_P (arg)) {
350
+ res_val_num = mpq_numref (res_val);
351
+ mpz_set (mpq_denref (res_val), mpq_denref (self_val));
352
+ mpz_get_struct (arg, arg_val_z);
353
+ mpz_mul (res_val_num, mpq_denref (self_val), arg_val_z);
323
354
  mpz_neg (res_val_num, res_val_num);
324
- mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
325
- } else if (FIXNUM_P(arg)) {
326
- res_val_num = mpq_numref(res_val);
327
- mpz_set (mpq_denref(res_val), mpq_denref(self_val));
328
- mpz_mul_si (res_val_num, mpq_denref(self_val), -FIX2NUM(arg));
329
- mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
330
- } else if (GMPF_P(arg)) {
355
+ mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
356
+ } else if (FIXNUM_P (arg)) {
357
+ res_val_num = mpq_numref (res_val);
358
+ mpz_set (mpq_denref (res_val), mpq_denref (self_val));
359
+ mpz_mul_si (res_val_num, mpq_denref (self_val), -FIX2NUM (arg));
360
+ mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
361
+ } else if (GMPF_P (arg)) {
331
362
  mpf_get_struct_prec (arg, arg_val_f, prec);
332
- mpf_make_struct_init(res, res_val_f, prec);
363
+ mpf_make_struct_init (res, res_val_f, prec);
333
364
  mpf_set_q (res_val_f, self_val);
334
365
  mpf_sub (res_val_f, res_val_f, arg_val_f);
335
- } else if (BIGNUM_P(arg)) {
336
- res_val_num = mpq_numref(res_val);
337
- mpz_set (mpq_denref(res_val), mpq_denref(self_val));
366
+ } else if (BIGNUM_P (arg)) {
367
+ res_val_num = mpq_numref (res_val);
368
+ mpz_set (mpq_denref (res_val), mpq_denref (self_val));
338
369
  mpz_set_bignum (res_val_num, arg);
339
- mpz_mul (res_val_num, res_val_num, mpq_denref(self_val));
370
+ mpz_mul (res_val_num, res_val_num, mpq_denref (self_val));
340
371
  mpz_neg (res_val_num, res_val_num);
341
- mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
372
+ mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
342
373
  } else {
343
374
  typeerror (ZQFXB);
344
375
  }
@@ -346,10 +377,12 @@ VALUE r_gmpq_sub(VALUE self, VALUE arg)
346
377
  }
347
378
 
348
379
  /*
380
+ * Document-method: *
349
381
  * call-seq:
350
382
  * p * q
351
383
  *
352
384
  * Multiplies _p_ with _q_. _q_ must be an instance of one of:
385
+ *
353
386
  * * GMP::Z
354
387
  * * Fixnum
355
388
  * * GMP::Q
@@ -418,10 +451,12 @@ VALUE r_gmpq_mul(VALUE self, VALUE arg)
418
451
  }
419
452
 
420
453
  /*
454
+ * Document-method: /
421
455
  * call-seq:
422
456
  * p / q
423
457
  *
424
458
  * Divides _p_ by _q_. _q_ must be an instance of one of:
459
+ *
425
460
  * * GMP::Z
426
461
  * * Fixnum
427
462
  * * GMP::Q
@@ -487,7 +522,6 @@ DEFUN_RAT2INT(ceil,mpz_cdiv_q)
487
522
 
488
523
  /*
489
524
  * Document-method: neg
490
- *
491
525
  * call-seq:
492
526
  * a.neg
493
527
  * -a
@@ -496,7 +530,6 @@ DEFUN_RAT2INT(ceil,mpz_cdiv_q)
496
530
  */
497
531
  /*
498
532
  * Document-method: neg!
499
- *
500
533
  * call-seq:
501
534
  * a.neg!
502
535
  *
@@ -505,12 +538,14 @@ DEFUN_RAT2INT(ceil,mpz_cdiv_q)
505
538
  DEFUN_RAT2RAT(neg, mpq_neg)
506
539
 
507
540
  /*
541
+ * Document-method: abs
508
542
  * call-seq:
509
543
  * p.abs
510
544
  *
511
545
  * Returns the absolute value of _p_.
512
546
  */
513
547
  /*
548
+ * Document-method: abs!
514
549
  * call-seq:
515
550
  * p.abs!
516
551
  *
@@ -519,10 +554,11 @@ DEFUN_RAT2RAT(neg, mpq_neg)
519
554
  DEFUN_RAT2RAT(abs, mpq_abs)
520
555
 
521
556
  /*
557
+ * Document-method: inv
522
558
  * call-seq:
523
559
  * p.inv
524
560
  *
525
- * Returns 1/<i>p</i>.
561
+ * Returns _1/p_.
526
562
  */
527
563
  VALUE r_gmpq_inv(VALUE self)
528
564
  {
@@ -539,10 +575,11 @@ VALUE r_gmpq_inv(VALUE self)
539
575
  }
540
576
 
541
577
  /*
578
+ * Document-method: inv!
542
579
  * call-seq:
543
580
  * p.inv!
544
581
  *
545
- * Sets _p_ to 1/<i>p</i>.
582
+ * Sets _p_ to _1/p_.
546
583
  */
547
584
  VALUE r_gmpq_inv_self(VALUE self)
548
585
  {
@@ -594,8 +631,17 @@ int mpq_cmp_value(MP_RAT *OP, VALUE arg)
594
631
  } else {
595
632
  typeerror(ZQFXB);
596
633
  }
634
+
635
+ return 0; /* should never get here */
597
636
  }
598
637
 
638
+ /*
639
+ * Document-method: ==
640
+ * call-seq:
641
+ * a == b
642
+ *
643
+ * Returns true if _a_ is equal to _b_, and false otherwise.
644
+ */
599
645
  VALUE r_gmpq_eq(VALUE self, VALUE arg)
600
646
  {
601
647
  MP_RAT *self_val, *arg_val_q;
@@ -613,7 +659,7 @@ VALUE r_gmpq_eq(VALUE self, VALUE arg)
613
659
  } else if (FIXNUM_P(arg)) {
614
660
  if (mpz_cmp_ui(mpq_denref(self_val), 1) != 0)
615
661
  return Qfalse;
616
- return (mpz_cmp_ui(mpq_numref(self_val),FIX2INT(arg))==0)?Qtrue:Qfalse;
662
+ return (mpz_cmp_si (mpq_numref (self_val), FIX2INT (arg)) == 0) ? Qtrue : Qfalse;
617
663
  } else if (BIGNUM_P(arg)) {
618
664
  if (mpz_cmp_ui(mpq_denref(self_val), 1) != 0)
619
665
  return Qfalse;
@@ -630,6 +676,17 @@ VALUE r_gmpq_eq(VALUE self, VALUE arg)
630
676
  }
631
677
  }
632
678
 
679
+ /*
680
+ * Document-method: <=>
681
+ * call-seq:
682
+ * a <=> b
683
+ *
684
+ * Returns negative if _a_ is less than _b_.
685
+ *
686
+ * Returns 0 if _a_ is equal to _b_.
687
+ *
688
+ * Returns positive if _a_ is greater than _b_.
689
+ */
633
690
  VALUE r_gmpq_cmp(VALUE self, VALUE arg)
634
691
  {
635
692
  MP_RAT *self_val;
@@ -644,11 +701,53 @@ VALUE r_gmpq_cmp(VALUE self, VALUE arg)
644
701
  return INT2FIX(-1);
645
702
  }
646
703
 
704
+ /*
705
+ * Document-method: <
706
+ * call-seq:
707
+ * a < b
708
+ *
709
+ * Returns whether _a_ is strictly less than _b_.
710
+ */
711
+
647
712
  DEFUN_RAT_CMP(lt,<)
713
+ /*
714
+ * Document-method: <=
715
+ * call-seq:
716
+ * a <= b
717
+ *
718
+ * Returns whether _a_ is less than or equal to _b_.
719
+ */
648
720
  DEFUN_RAT_CMP(le,<=)
721
+
722
+ /*
723
+ * Document-method: >
724
+ * call-seq:
725
+ * a > b
726
+ *
727
+ * Returns whether _a_ is strictly greater than _b_.
728
+ */
649
729
  DEFUN_RAT_CMP(gt,>)
730
+
731
+ /*
732
+ * Document-method: >=
733
+ * call-seq:
734
+ * a >= b
735
+ *
736
+ * Returns whether _a_ is greater than or equal to _b_.
737
+ */
650
738
  DEFUN_RAT_CMP(ge,>=)
651
739
 
740
+ /*
741
+ * Document-method: cmpabs
742
+ * call-seq:
743
+ * a.cmpabs(b)
744
+ *
745
+ * Returns negative if _abs(a)_ is less than _abs(b)_.
746
+ *
747
+ * Returns 0 if _abs(a)_ is equal to _abs(b)_.
748
+ *
749
+ * Returns positive if _abs(a)_ is greater than _abs(b)_.
750
+ */
652
751
  static VALUE r_gmpq_cmpabs(VALUE self, VALUE arg)
653
752
  {
654
753
  MP_RAT *arg_val_q, *self_val;
@@ -714,9 +813,12 @@ static VALUE r_gmpq_cmpabs(VALUE self, VALUE arg)
714
813
  } else {
715
814
  typeerror (ZQFXB);
716
815
  }
816
+
817
+ return Qnil; /* should never get here */
717
818
  }
718
819
 
719
820
  /*
821
+ * Document-method: sgn
720
822
  * call-seq:
721
823
  * p.sgn
722
824
  *
@@ -730,14 +832,15 @@ VALUE r_gmpq_sgn(VALUE self)
730
832
  }
731
833
 
732
834
  /*
835
+ * Document-method: eql?
733
836
  * call-seq:
734
837
  * a.eql?(b)
735
838
  *
736
839
  * @since 0.5.47
737
840
  *
738
- * Returns true if _a_ is equal to _b_. _a_ and _b_ must then be equal in cardinality,
739
- * and both be instances of GMP::Q. Otherwise, returns false. a.eql?(b) if and only if
740
- * b.class == GMP::Q, and a.hash == b.hash.
841
+ * Returns whether if _a_ is equal to _b_. _a_ and _b_ must be equal in
842
+ * cardinality, and both be instances of GMP::Q to return true. `a.eql?(b)` if
843
+ * and only if `b.class == GMP::Q`, and `a.hash == b.hash`.
741
844
  */
742
845
  VALUE r_gmpq_eql(VALUE self, VALUE arg)
743
846
  {
@@ -754,14 +857,16 @@ VALUE r_gmpq_eql(VALUE self, VALUE arg)
754
857
  }
755
858
 
756
859
  /*
860
+ * Document-method: hash
757
861
  * call-seq:
758
862
  * a.hash
759
863
  *
760
864
  * @since 0.5.47
761
865
  *
762
- * Returns the computed hash value of _a_. This method first converts _a_ into a String
763
- * (base 10), then calls String#hash on the result, returning the hash value. a.eql?(b)
764
- * if and only if b.class == GMP::Q, and a.hash == b.hash.
866
+ * Returns the computed hash value of _a_. This method first converts _a_ into
867
+ * a String (base 10), then calls String#hash on the result, returning the hash
868
+ * value. `a.eql?(b)` if and only if `b.class == GMP::Q`, and
869
+ * `a.hash == b.hash`.
765
870
  */
766
871
  VALUE r_gmpq_hash(VALUE self)
767
872
  {
@@ -774,7 +879,14 @@ VALUE r_gmpq_hash(VALUE self)
774
879
  * Applying Integer Functions *
775
880
  **********************************************************************/
776
881
 
777
- VALUE r_gmpq_num(VALUE self)
882
+ /*
883
+ * Document-method: num
884
+ * call-seq:
885
+ * a.num
886
+ *
887
+ * Returns the numerator of _a_.
888
+ */
889
+ VALUE r_gmpq_get_num(VALUE self)
778
890
  {
779
891
  MP_RAT *self_val;
780
892
  MP_INT *res_val;
@@ -785,7 +897,15 @@ VALUE r_gmpq_num(VALUE self)
785
897
  return res;
786
898
  }
787
899
 
788
- VALUE r_gmpq_den(VALUE self)
900
+
901
+ /*
902
+ * Document-method: den
903
+ * call-seq:
904
+ * a.den
905
+ *
906
+ * Returns the denominator of _a_.
907
+ */
908
+ VALUE r_gmpq_get_den(VALUE self)
789
909
  {
790
910
  MP_RAT *self_val;
791
911
  MP_INT *res_val;
@@ -818,7 +938,9 @@ void init_gmpq()
818
938
  rb_define_method(cGMP_Q, "+", r_gmpq_add, 1);
819
939
  rb_define_method(cGMP_Q, "-", r_gmpq_sub, 1);
820
940
  rb_define_method(cGMP_Q, "*", r_gmpq_mul, 1);
941
+ /* TODO rb_define_method(cGMP_Q, "mul_2exp", r_gmpq_mul_2exp, 1); */
821
942
  rb_define_method(cGMP_Q, "/", r_gmpq_div, 1);
943
+ /* TODO rb_define_method(cGMP_Q, "div_2exp", r_gmpq_div_2exp, 1); */
822
944
  rb_define_method(cGMP_Q, "-@", r_gmpq_neg, 0);
823
945
  rb_define_alias( cGMP_Q, "neg", "-@");
824
946
  rb_define_method(cGMP_Q, "neg!", r_gmpq_neg_self, 0);
@@ -839,6 +961,12 @@ void init_gmpq()
839
961
 
840
962
  rb_define_method(cGMP_Q, "eql?", r_gmpq_eql, 1);
841
963
  rb_define_method(cGMP_Q, "hash", r_gmpq_hash, 0);
964
+
965
+ // Applying Integer Functions to Rationals
966
+ rb_define_method(cGMP_Q, "num", r_gmpq_get_num, 0);
967
+ rb_define_method(cGMP_Q, "den", r_gmpq_get_den, 0);
968
+ /* TODO rb_define_method(cGMP_Q, "num=", r_gmpq_set_num, 0); */
969
+ /* TODO rb_define_method(cGMP_Q, "den=", r_gmpq_set_den, 0); */
842
970
 
843
971
  // _unsorted_
844
972
  rb_define_method(cGMP_Q, "floor", r_gmpq_floor, 0);