Ruby  2.0.0p247(2013-06-27revision41674)
rational.c
Go to the documentation of this file.
1 /*
2  rational.c: Coded by Tadayoshi Funaba 2008-2012
3 
4  This implementation is based on Keiju Ishitsuka's Rational library
5  which is written in ruby.
6 */
7 
8 #include "ruby.h"
9 #include "internal.h"
10 #include <math.h>
11 #include <float.h>
12 
13 #ifdef HAVE_IEEEFP_H
14 #include <ieeefp.h>
15 #endif
16 
17 #define NDEBUG
18 #include <assert.h>
19 
20 #define ZERO INT2FIX(0)
21 #define ONE INT2FIX(1)
22 #define TWO INT2FIX(2)
23 
25 
29 
30 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
31 
32 #define binop(n,op) \
33 inline static VALUE \
34 f_##n(VALUE x, VALUE y)\
35 {\
36  return rb_funcall(x, (op), 1, y);\
37 }
38 
39 #define fun1(n) \
40 inline static VALUE \
41 f_##n(VALUE x)\
42 {\
43  return rb_funcall(x, id_##n, 0);\
44 }
45 
46 #define fun2(n) \
47 inline static VALUE \
48 f_##n(VALUE x, VALUE y)\
49 {\
50  return rb_funcall(x, id_##n, 1, y);\
51 }
52 
53 inline static VALUE
55 {
56  if (FIXNUM_P(y) && FIX2LONG(y) == 0)
57  return x;
58  else if (FIXNUM_P(x) && FIX2LONG(x) == 0)
59  return y;
60  return rb_funcall(x, '+', 1, y);
61 }
62 
63 inline static VALUE
65 {
66  if (FIXNUM_P(x) && FIXNUM_P(y)) {
67  long c = FIX2LONG(x) - FIX2LONG(y);
68  if (c > 0)
69  c = 1;
70  else if (c < 0)
71  c = -1;
72  return INT2FIX(c);
73  }
74  return rb_funcall(x, id_cmp, 1, y);
75 }
76 
77 inline static VALUE
79 {
80  if (FIXNUM_P(y) && FIX2LONG(y) == 1)
81  return x;
82  return rb_funcall(x, '/', 1, y);
83 }
84 
85 inline static VALUE
87 {
88  if (FIXNUM_P(x) && FIXNUM_P(y))
89  return f_boolcast(FIX2LONG(x) > FIX2LONG(y));
90  return rb_funcall(x, '>', 1, y);
91 }
92 
93 inline static VALUE
95 {
96  if (FIXNUM_P(x) && FIXNUM_P(y))
97  return f_boolcast(FIX2LONG(x) < FIX2LONG(y));
98  return rb_funcall(x, '<', 1, y);
99 }
100 
101 binop(mod, '%')
102 
103 inline static VALUE
105 {
106  if (FIXNUM_P(y)) {
107  long iy = FIX2LONG(y);
108  if (iy == 0) {
109  if (FIXNUM_P(x) || RB_TYPE_P(x, T_BIGNUM))
110  return ZERO;
111  }
112  else if (iy == 1)
113  return x;
114  }
115  else if (FIXNUM_P(x)) {
116  long ix = FIX2LONG(x);
117  if (ix == 0) {
118  if (FIXNUM_P(y) || RB_TYPE_P(y, T_BIGNUM))
119  return ZERO;
120  }
121  else if (ix == 1)
122  return y;
123  }
124  return rb_funcall(x, '*', 1, y);
125 }
126 
127 inline static VALUE
129 {
130  if (FIXNUM_P(y) && FIX2LONG(y) == 0)
131  return x;
132  return rb_funcall(x, '-', 1, y);
133 }
134 
135 fun1(abs)
136 fun1(floor)
137 fun1(inspect)
138 fun1(integer_p)
139 fun1(negate)
140 
141 inline static VALUE
143 {
144  if (RB_TYPE_P(x, T_STRING))
145  return rb_str_to_inum(x, 10, 0);
146  return rb_funcall(x, id_to_i, 0);
147 }
148 inline static VALUE
150 {
151  if (RB_TYPE_P(x, T_STRING))
152  return DBL2NUM(rb_str_to_dbl(x, 0));
153  return rb_funcall(x, id_to_f, 0);
154 }
155 
156 fun1(to_s)
157 fun1(truncate)
158 
159 inline static VALUE
161 {
162  if (FIXNUM_P(x) && FIXNUM_P(y))
163  return f_boolcast(FIX2LONG(x) == FIX2LONG(y));
164  return rb_funcall(x, id_eqeq_p, 1, y);
165 }
166 
167 fun2(expt)
168 fun2(fdiv)
169 fun2(idiv)
170 
171 #define f_expt10(x) f_expt(INT2FIX(10), x)
172 
173 inline static VALUE
175 {
176  if (FIXNUM_P(x))
177  return f_boolcast(FIX2LONG(x) < 0);
178  return rb_funcall(x, '<', 1, ZERO);
179 }
180 
181 #define f_positive_p(x) (!f_negative_p(x))
182 
183 inline static VALUE
185 {
186  switch (TYPE(x)) {
187  case T_FIXNUM:
188  return f_boolcast(FIX2LONG(x) == 0);
189  case T_BIGNUM:
190  return Qfalse;
191  case T_RATIONAL:
192  {
193  VALUE num = RRATIONAL(x)->num;
194 
195  return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 0);
196  }
197  }
198  return rb_funcall(x, id_eqeq_p, 1, ZERO);
199 }
200 
201 #define f_nonzero_p(x) (!f_zero_p(x))
202 
203 inline static VALUE
205 {
206  switch (TYPE(x)) {
207  case T_FIXNUM:
208  return f_boolcast(FIX2LONG(x) == 1);
209  case T_BIGNUM:
210  return Qfalse;
211  case T_RATIONAL:
212  {
213  VALUE num = RRATIONAL(x)->num;
214  VALUE den = RRATIONAL(x)->den;
215 
216  return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 1 &&
217  FIXNUM_P(den) && FIX2LONG(den) == 1);
218  }
219  }
220  return rb_funcall(x, id_eqeq_p, 1, ONE);
221 }
222 
223 inline static VALUE
225 {
226  switch (TYPE(x)) {
227  case T_FIXNUM:
228  return f_boolcast(FIX2LONG(x) == -1);
229  case T_BIGNUM:
230  return Qfalse;
231  case T_RATIONAL:
232  {
233  VALUE num = RRATIONAL(x)->num;
234  VALUE den = RRATIONAL(x)->den;
235 
236  return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == -1 &&
237  FIXNUM_P(den) && FIX2LONG(den) == 1);
238  }
239  }
240  return rb_funcall(x, id_eqeq_p, 1, INT2FIX(-1));
241 }
242 
243 inline static VALUE
245 {
246  return rb_obj_is_kind_of(x, c);
247 }
248 
249 inline static VALUE
251 {
252  return f_kind_of_p(x, rb_cNumeric);
253 }
254 
255 inline static VALUE
257 {
258  return f_kind_of_p(x, rb_cInteger);
259 }
260 
261 inline static VALUE
263 {
264  return f_kind_of_p(x, rb_cFloat);
265 }
266 
267 inline static VALUE
269 {
270  return f_kind_of_p(x, rb_cRational);
271 }
272 
273 #define k_exact_p(x) (!k_float_p(x))
274 #define k_inexact_p(x) k_float_p(x)
275 
276 #define k_exact_zero_p(x) (k_exact_p(x) && f_zero_p(x))
277 #define k_exact_one_p(x) (k_exact_p(x) && f_one_p(x))
278 
279 #ifndef NDEBUG
280 #define f_gcd f_gcd_orig
281 #endif
282 
283 inline static long
284 i_gcd(long x, long y)
285 {
286  if (x < 0)
287  x = -x;
288  if (y < 0)
289  y = -y;
290 
291  if (x == 0)
292  return y;
293  if (y == 0)
294  return x;
295 
296  while (x > 0) {
297  long t = x;
298  x = y % x;
299  y = t;
300  }
301  return y;
302 }
303 
304 inline static VALUE
306 {
307  VALUE z;
308 
309  if (FIXNUM_P(x) && FIXNUM_P(y))
310  return LONG2NUM(i_gcd(FIX2LONG(x), FIX2LONG(y)));
311 
312  if (f_negative_p(x))
313  x = f_negate(x);
314  if (f_negative_p(y))
315  y = f_negate(y);
316 
317  if (f_zero_p(x))
318  return y;
319  if (f_zero_p(y))
320  return x;
321 
322  for (;;) {
323  if (FIXNUM_P(x)) {
324  if (FIX2LONG(x) == 0)
325  return y;
326  if (FIXNUM_P(y))
327  return LONG2NUM(i_gcd(FIX2LONG(x), FIX2LONG(y)));
328  }
329  z = x;
330  x = f_mod(y, x);
331  y = z;
332  }
333  /* NOTREACHED */
334 }
335 
336 #ifndef NDEBUG
337 #undef f_gcd
338 
339 inline static VALUE
340 f_gcd(VALUE x, VALUE y)
341 {
342  VALUE r = f_gcd_orig(x, y);
343  if (f_nonzero_p(r)) {
344  assert(f_zero_p(f_mod(x, r)));
345  assert(f_zero_p(f_mod(y, r)));
346  }
347  return r;
348 }
349 #endif
350 
351 inline static VALUE
353 {
354  if (f_zero_p(x) || f_zero_p(y))
355  return ZERO;
356  return f_abs(f_mul(f_div(x, f_gcd(x, y)), y));
357 }
358 
359 #define get_dat1(x) \
360  struct RRational *dat;\
361  dat = ((struct RRational *)(x))
362 
363 #define get_dat2(x,y) \
364  struct RRational *adat, *bdat;\
365  adat = ((struct RRational *)(x));\
366  bdat = ((struct RRational *)(y))
367 
368 inline static VALUE
370 {
371  NEWOBJ_OF(obj, struct RRational, klass, T_RATIONAL);
372 
373  obj->num = num;
374  obj->den = den;
375 
376  return (VALUE)obj;
377 }
378 
379 static VALUE
381 {
382  return nurat_s_new_internal(klass, ZERO, ONE);
383 }
384 
385 #define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0")
386 
387 #if 0
388 static VALUE
389 nurat_s_new_bang(int argc, VALUE *argv, VALUE klass)
390 {
391  VALUE num, den;
392 
393  switch (rb_scan_args(argc, argv, "11", &num, &den)) {
394  case 1:
395  if (!k_integer_p(num))
396  num = f_to_i(num);
397  den = ONE;
398  break;
399  default:
400  if (!k_integer_p(num))
401  num = f_to_i(num);
402  if (!k_integer_p(den))
403  den = f_to_i(den);
404 
405  switch (FIX2INT(f_cmp(den, ZERO))) {
406  case -1:
407  num = f_negate(num);
408  den = f_negate(den);
409  break;
410  case 0:
412  break;
413  }
414  break;
415  }
416 
417  return nurat_s_new_internal(klass, num, den);
418 }
419 #endif
420 
421 inline static VALUE
423 {
424  return nurat_s_new_internal(klass, x, ONE);
425 }
426 
427 inline static VALUE
429 {
430  assert(f_positive_p(y));
431  assert(f_nonzero_p(y));
432  return nurat_s_new_internal(klass, x, y);
433 }
434 
435 #ifdef CANONICALIZATION_FOR_MATHN
436 #define CANON
437 #endif
438 
439 #ifdef CANON
440 static int canonicalization = 0;
441 
444 {
445  canonicalization = f;
446 }
447 #endif
448 
449 inline static void
451 {
452  switch (TYPE(num)) {
453  case T_FIXNUM:
454  case T_BIGNUM:
455  break;
456  default:
457  if (!k_numeric_p(num) || !f_integer_p(num))
458  rb_raise(rb_eTypeError, "not an integer");
459  }
460 }
461 
462 inline static VALUE
464 {
465  nurat_int_check(num);
466  if (!k_integer_p(num))
467  num = f_to_i(num);
468  return num;
469 }
470 
471 inline static VALUE
473 {
474  VALUE gcd;
475 
476  switch (FIX2INT(f_cmp(den, ZERO))) {
477  case -1:
478  num = f_negate(num);
479  den = f_negate(den);
480  break;
481  case 0:
483  break;
484  }
485 
486  gcd = f_gcd(num, den);
487  num = f_idiv(num, gcd);
488  den = f_idiv(den, gcd);
489 
490 #ifdef CANON
491  if (f_one_p(den) && canonicalization)
492  return num;
493 #endif
494  return nurat_s_new_internal(klass, num, den);
495 }
496 
497 inline static VALUE
499 {
500  switch (FIX2INT(f_cmp(den, ZERO))) {
501  case -1:
502  num = f_negate(num);
503  den = f_negate(den);
504  break;
505  case 0:
507  break;
508  }
509 
510 #ifdef CANON
511  if (f_one_p(den) && canonicalization)
512  return num;
513 #endif
514  return nurat_s_new_internal(klass, num, den);
515 }
516 
517 static VALUE
519 {
520  VALUE num, den;
521 
522  switch (rb_scan_args(argc, argv, "11", &num, &den)) {
523  case 1:
524  num = nurat_int_value(num);
525  den = ONE;
526  break;
527  default:
528  num = nurat_int_value(num);
529  den = nurat_int_value(den);
530  break;
531  }
532 
533  return nurat_s_canonicalize_internal(klass, num, den);
534 }
535 
536 inline static VALUE
538 {
539  assert(!k_rational_p(x));
540  return nurat_s_canonicalize_internal(klass, x, ONE);
541 }
542 
543 inline static VALUE
545 {
546  assert(!k_rational_p(x));
547  assert(!k_rational_p(y));
548  return nurat_s_canonicalize_internal(klass, x, y);
549 }
550 
551 inline static VALUE
553 {
554  assert(!k_rational_p(x));
556 }
557 
558 inline static VALUE
560 {
561  assert(!k_rational_p(x));
562  assert(!k_rational_p(y));
563  return nurat_s_canonicalize_internal_no_reduce(klass, x, y);
564 }
565 
566 /*
567  * call-seq:
568  * Rational(x[, y]) -> numeric
569  *
570  * Returns x/y;
571  *
572  * Rational(1, 2) #=> (1/2)
573  * Rational('1/2') #=> (1/2)
574  *
575  * Syntax of string form:
576  *
577  * string form = extra spaces , rational , extra spaces ;
578  * rational = [ sign ] , unsigned rational ;
579  * unsigned rational = numerator | numerator , "/" , denominator ;
580  * numerator = integer part | fractional part | integer part , fractional part ;
581  * denominator = digits ;
582  * integer part = digits ;
583  * fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
584  * sign = "-" | "+" ;
585  * digits = digit , { digit | "_" , digit } ;
586  * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
587  * extra spaces = ? \s* ? ;
588  *
589  * See String#to_r.
590  */
591 static VALUE
593 {
594  return rb_funcall2(rb_cRational, id_convert, argc, argv);
595 }
596 
597 /*
598  * call-seq:
599  * rat.numerator -> integer
600  *
601  * Returns the numerator.
602  *
603  * Rational(7).numerator #=> 7
604  * Rational(7, 1).numerator #=> 7
605  * Rational(9, -4).numerator #=> -9
606  * Rational(-2, -10).numerator #=> 1
607  */
608 static VALUE
610 {
611  get_dat1(self);
612  return dat->num;
613 }
614 
615 /*
616  * call-seq:
617  * rat.denominator -> integer
618  *
619  * Returns the denominator (always positive).
620  *
621  * Rational(7).denominator #=> 1
622  * Rational(7, 1).denominator #=> 1
623  * Rational(9, -4).denominator #=> 4
624  * Rational(-2, -10).denominator #=> 5
625  * rat.numerator.gcd(rat.denominator) #=> 1
626  */
627 static VALUE
629 {
630  get_dat1(self);
631  return dat->den;
632 }
633 
634 #ifndef NDEBUG
635 #define f_imul f_imul_orig
636 #endif
637 
638 inline static VALUE
639 f_imul(long a, long b)
640 {
641  VALUE r;
642 
643  if (a == 0 || b == 0)
644  return ZERO;
645  else if (a == 1)
646  return LONG2NUM(b);
647  else if (b == 1)
648  return LONG2NUM(a);
649 
650  if (MUL_OVERFLOW_LONG_P(a, b))
651  r = rb_big_mul(rb_int2big(a), rb_int2big(b));
652  else
653  r = LONG2NUM(a * b);
654  return r;
655 }
656 
657 #ifndef NDEBUG
658 #undef f_imul
659 
660 inline static VALUE
661 f_imul(long x, long y)
662 {
663  VALUE r = f_imul_orig(x, y);
664  assert(f_eqeq_p(r, f_mul(LONG2NUM(x), LONG2NUM(y))));
665  return r;
666 }
667 #endif
668 
669 inline static VALUE
670 f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
671 {
672  VALUE num, den;
673 
674  if (FIXNUM_P(anum) && FIXNUM_P(aden) &&
675  FIXNUM_P(bnum) && FIXNUM_P(bden)) {
676  long an = FIX2LONG(anum);
677  long ad = FIX2LONG(aden);
678  long bn = FIX2LONG(bnum);
679  long bd = FIX2LONG(bden);
680  long ig = i_gcd(ad, bd);
681 
682  VALUE g = LONG2NUM(ig);
683  VALUE a = f_imul(an, bd / ig);
684  VALUE b = f_imul(bn, ad / ig);
685  VALUE c;
686 
687  if (k == '+')
688  c = f_add(a, b);
689  else
690  c = f_sub(a, b);
691 
692  b = f_idiv(aden, g);
693  g = f_gcd(c, g);
694  num = f_idiv(c, g);
695  a = f_idiv(bden, g);
696  den = f_mul(a, b);
697  }
698  else {
699  VALUE g = f_gcd(aden, bden);
700  VALUE a = f_mul(anum, f_idiv(bden, g));
701  VALUE b = f_mul(bnum, f_idiv(aden, g));
702  VALUE c;
703 
704  if (k == '+')
705  c = f_add(a, b);
706  else
707  c = f_sub(a, b);
708 
709  b = f_idiv(aden, g);
710  g = f_gcd(c, g);
711  num = f_idiv(c, g);
712  a = f_idiv(bden, g);
713  den = f_mul(a, b);
714  }
715  return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
716 }
717 
718 /*
719  * call-seq:
720  * rat + numeric -> numeric
721  *
722  * Performs addition.
723  *
724  * Rational(2, 3) + Rational(2, 3) #=> (4/3)
725  * Rational(900) + Rational(1) #=> (900/1)
726  * Rational(-2, 9) + Rational(-9, 2) #=> (-85/18)
727  * Rational(9, 8) + 4 #=> (41/8)
728  * Rational(20, 9) + 9.8 #=> 12.022222222222222
729  */
730 static VALUE
731 nurat_add(VALUE self, VALUE other)
732 {
733  switch (TYPE(other)) {
734  case T_FIXNUM:
735  case T_BIGNUM:
736  {
737  get_dat1(self);
738 
739  return f_addsub(self,
740  dat->num, dat->den,
741  other, ONE, '+');
742  }
743  case T_FLOAT:
744  return f_add(f_to_f(self), other);
745  case T_RATIONAL:
746  {
747  get_dat2(self, other);
748 
749  return f_addsub(self,
750  adat->num, adat->den,
751  bdat->num, bdat->den, '+');
752  }
753  default:
754  return rb_num_coerce_bin(self, other, '+');
755  }
756 }
757 
758 /*
759  * call-seq:
760  * rat - numeric -> numeric
761  *
762  * Performs subtraction.
763  *
764  * Rational(2, 3) - Rational(2, 3) #=> (0/1)
765  * Rational(900) - Rational(1) #=> (899/1)
766  * Rational(-2, 9) - Rational(-9, 2) #=> (77/18)
767  * Rational(9, 8) - 4 #=> (23/8)
768  * Rational(20, 9) - 9.8 #=> -7.577777777777778
769  */
770 static VALUE
771 nurat_sub(VALUE self, VALUE other)
772 {
773  switch (TYPE(other)) {
774  case T_FIXNUM:
775  case T_BIGNUM:
776  {
777  get_dat1(self);
778 
779  return f_addsub(self,
780  dat->num, dat->den,
781  other, ONE, '-');
782  }
783  case T_FLOAT:
784  return f_sub(f_to_f(self), other);
785  case T_RATIONAL:
786  {
787  get_dat2(self, other);
788 
789  return f_addsub(self,
790  adat->num, adat->den,
791  bdat->num, bdat->den, '-');
792  }
793  default:
794  return rb_num_coerce_bin(self, other, '-');
795  }
796 }
797 
798 inline static VALUE
799 f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
800 {
801  VALUE num, den;
802 
803  if (k == '/') {
804  VALUE t;
805 
806  if (f_negative_p(bnum)) {
807  anum = f_negate(anum);
808  bnum = f_negate(bnum);
809  }
810  t = bnum;
811  bnum = bden;
812  bden = t;
813  }
814 
815  if (FIXNUM_P(anum) && FIXNUM_P(aden) &&
816  FIXNUM_P(bnum) && FIXNUM_P(bden)) {
817  long an = FIX2LONG(anum);
818  long ad = FIX2LONG(aden);
819  long bn = FIX2LONG(bnum);
820  long bd = FIX2LONG(bden);
821  long g1 = i_gcd(an, bd);
822  long g2 = i_gcd(ad, bn);
823 
824  num = f_imul(an / g1, bn / g2);
825  den = f_imul(ad / g2, bd / g1);
826  }
827  else {
828  VALUE g1 = f_gcd(anum, bden);
829  VALUE g2 = f_gcd(aden, bnum);
830 
831  num = f_mul(f_idiv(anum, g1), f_idiv(bnum, g2));
832  den = f_mul(f_idiv(aden, g2), f_idiv(bden, g1));
833  }
834  return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
835 }
836 
837 /*
838  * call-seq:
839  * rat * numeric -> numeric
840  *
841  * Performs multiplication.
842  *
843  * Rational(2, 3) * Rational(2, 3) #=> (4/9)
844  * Rational(900) * Rational(1) #=> (900/1)
845  * Rational(-2, 9) * Rational(-9, 2) #=> (1/1)
846  * Rational(9, 8) * 4 #=> (9/2)
847  * Rational(20, 9) * 9.8 #=> 21.77777777777778
848  */
849 static VALUE
850 nurat_mul(VALUE self, VALUE other)
851 {
852  switch (TYPE(other)) {
853  case T_FIXNUM:
854  case T_BIGNUM:
855  {
856  get_dat1(self);
857 
858  return f_muldiv(self,
859  dat->num, dat->den,
860  other, ONE, '*');
861  }
862  case T_FLOAT:
863  return f_mul(f_to_f(self), other);
864  case T_RATIONAL:
865  {
866  get_dat2(self, other);
867 
868  return f_muldiv(self,
869  adat->num, adat->den,
870  bdat->num, bdat->den, '*');
871  }
872  default:
873  return rb_num_coerce_bin(self, other, '*');
874  }
875 }
876 
877 /*
878  * call-seq:
879  * rat / numeric -> numeric
880  * rat.quo(numeric) -> numeric
881  *
882  * Performs division.
883  *
884  * Rational(2, 3) / Rational(2, 3) #=> (1/1)
885  * Rational(900) / Rational(1) #=> (900/1)
886  * Rational(-2, 9) / Rational(-9, 2) #=> (4/81)
887  * Rational(9, 8) / 4 #=> (9/32)
888  * Rational(20, 9) / 9.8 #=> 0.22675736961451246
889  */
890 static VALUE
891 nurat_div(VALUE self, VALUE other)
892 {
893  switch (TYPE(other)) {
894  case T_FIXNUM:
895  case T_BIGNUM:
896  if (f_zero_p(other))
898  {
899  get_dat1(self);
900 
901  return f_muldiv(self,
902  dat->num, dat->den,
903  other, ONE, '/');
904  }
905  case T_FLOAT:
906  {
907  double x = RFLOAT_VALUE(other), den;
908  get_dat1(self);
909 
910  if (isnan(x)) return DBL2NUM(NAN);
911  if (isinf(x)) return INT2FIX(0);
912  if (x != 0.0 && modf(x, &den) == 0.0) {
913  return rb_rational_raw2(dat->num, f_mul(rb_dbl2big(den), dat->den));
914  }
915  }
916  return rb_funcall(f_to_f(self), '/', 1, other);
917  case T_RATIONAL:
918  if (f_zero_p(other))
920  {
921  get_dat2(self, other);
922 
923  if (f_one_p(self))
924  return f_rational_new_no_reduce2(CLASS_OF(self),
925  bdat->den, bdat->num);
926 
927  return f_muldiv(self,
928  adat->num, adat->den,
929  bdat->num, bdat->den, '/');
930  }
931  default:
932  return rb_num_coerce_bin(self, other, '/');
933  }
934 }
935 
936 /*
937  * call-seq:
938  * rat.fdiv(numeric) -> float
939  *
940  * Performs division and returns the value as a float.
941  *
942  * Rational(2, 3).fdiv(1) #=> 0.6666666666666666
943  * Rational(2, 3).fdiv(0.5) #=> 1.3333333333333333
944  * Rational(2).fdiv(3) #=> 0.6666666666666666
945  */
946 static VALUE
947 nurat_fdiv(VALUE self, VALUE other)
948 {
949  if (f_zero_p(other))
950  return f_div(self, f_to_f(other));
951  return f_to_f(f_div(self, other));
952 }
953 
954 inline static VALUE
955 f_odd_p(VALUE integer)
956 {
957  if (rb_funcall(integer, '%', 1, INT2FIX(2)) != INT2FIX(0)) {
958  return Qtrue;
959  }
960  return Qfalse;
961 
962 }
963 
964 /*
965  * call-seq:
966  * rat ** numeric -> numeric
967  *
968  * Performs exponentiation.
969  *
970  * Rational(2) ** Rational(3) #=> (8/1)
971  * Rational(10) ** -2 #=> (1/100)
972  * Rational(10) ** -2.0 #=> 0.01
973  * Rational(-4) ** Rational(1,2) #=> (1.2246063538223773e-16+2.0i)
974  * Rational(1, 2) ** 0 #=> (1/1)
975  * Rational(1, 2) ** 0.0 #=> 1.0
976  */
977 static VALUE
978 nurat_expt(VALUE self, VALUE other)
979 {
980  if (k_numeric_p(other) && k_exact_zero_p(other))
981  return f_rational_new_bang1(CLASS_OF(self), ONE);
982 
983  if (k_rational_p(other)) {
984  get_dat1(other);
985 
986  if (f_one_p(dat->den))
987  other = dat->num; /* c14n */
988  }
989 
990  /* Deal with special cases of 0**n and 1**n */
991  if (k_numeric_p(other) && k_exact_p(other)) {
992  get_dat1(self);
993  if (f_one_p(dat->den))
994  if (f_one_p(dat->num))
995  return f_rational_new_bang1(CLASS_OF(self), ONE);
996  else if (f_minus_one_p(dat->num) && k_integer_p(other))
997  return f_rational_new_bang1(CLASS_OF(self), INT2FIX(f_odd_p(other) ? -1 : 1));
998  else if (f_zero_p(dat->num))
999  if (FIX2INT(f_cmp(other, ZERO)) == -1)
1000  rb_raise_zerodiv();
1001  else
1002  return f_rational_new_bang1(CLASS_OF(self), ZERO);
1003  }
1004 
1005  /* General case */
1006  switch (TYPE(other)) {
1007  case T_FIXNUM:
1008  {
1009  VALUE num, den;
1010 
1011  get_dat1(self);
1012 
1013  switch (FIX2INT(f_cmp(other, ZERO))) {
1014  case 1:
1015  num = f_expt(dat->num, other);
1016  den = f_expt(dat->den, other);
1017  break;
1018  case -1:
1019  num = f_expt(dat->den, f_negate(other));
1020  den = f_expt(dat->num, f_negate(other));
1021  break;
1022  default:
1023  num = ONE;
1024  den = ONE;
1025  break;
1026  }
1027  return f_rational_new2(CLASS_OF(self), num, den);
1028  }
1029  case T_BIGNUM:
1030  rb_warn("in a**b, b may be too big");
1031  /* fall through */
1032  case T_FLOAT:
1033  case T_RATIONAL:
1034  return f_expt(f_to_f(self), other);
1035  default:
1036  return rb_num_coerce_bin(self, other, id_expt);
1037  }
1038 }
1039 
1040 /*
1041  * call-seq:
1042  * rational <=> numeric -> -1, 0, +1 or nil
1043  *
1044  * Performs comparison and returns -1, 0, or +1.
1045  *
1046  * +nil+ is returned if the two values are incomparable.
1047  *
1048  * Rational(2, 3) <=> Rational(2, 3) #=> 0
1049  * Rational(5) <=> 5 #=> 0
1050  * Rational(2,3) <=> Rational(1,3) #=> 1
1051  * Rational(1,3) <=> 1 #=> -1
1052  * Rational(1,3) <=> 0.3 #=> 1
1053  */
1054 static VALUE
1055 nurat_cmp(VALUE self, VALUE other)
1056 {
1057  switch (TYPE(other)) {
1058  case T_FIXNUM:
1059  case T_BIGNUM:
1060  {
1061  get_dat1(self);
1062 
1063  if (FIXNUM_P(dat->den) && FIX2LONG(dat->den) == 1)
1064  return f_cmp(dat->num, other); /* c14n */
1065  return f_cmp(self, f_rational_new_bang1(CLASS_OF(self), other));
1066  }
1067  case T_FLOAT:
1068  return f_cmp(f_to_f(self), other);
1069  case T_RATIONAL:
1070  {
1071  VALUE num1, num2;
1072 
1073  get_dat2(self, other);
1074 
1075  if (FIXNUM_P(adat->num) && FIXNUM_P(adat->den) &&
1076  FIXNUM_P(bdat->num) && FIXNUM_P(bdat->den)) {
1077  num1 = f_imul(FIX2LONG(adat->num), FIX2LONG(bdat->den));
1078  num2 = f_imul(FIX2LONG(bdat->num), FIX2LONG(adat->den));
1079  }
1080  else {
1081  num1 = f_mul(adat->num, bdat->den);
1082  num2 = f_mul(bdat->num, adat->den);
1083  }
1084  return f_cmp(f_sub(num1, num2), ZERO);
1085  }
1086  default:
1087  return rb_num_coerce_cmp(self, other, id_cmp);
1088  }
1089 }
1090 
1091 /*
1092  * call-seq:
1093  * rat == object -> true or false
1094  *
1095  * Returns true if rat equals object numerically.
1096  *
1097  * Rational(2, 3) == Rational(2, 3) #=> true
1098  * Rational(5) == 5 #=> true
1099  * Rational(0) == 0.0 #=> true
1100  * Rational('1/3') == 0.33 #=> false
1101  * Rational('1/2') == '1/2' #=> false
1102  */
1103 static VALUE
1105 {
1106  switch (TYPE(other)) {
1107  case T_FIXNUM:
1108  case T_BIGNUM:
1109  {
1110  get_dat1(self);
1111 
1112  if (f_zero_p(dat->num) && f_zero_p(other))
1113  return Qtrue;
1114 
1115  if (!FIXNUM_P(dat->den))
1116  return Qfalse;
1117  if (FIX2LONG(dat->den) != 1)
1118  return Qfalse;
1119  if (f_eqeq_p(dat->num, other))
1120  return Qtrue;
1121  return Qfalse;
1122  }
1123  case T_FLOAT:
1124  return f_eqeq_p(f_to_f(self), other);
1125  case T_RATIONAL:
1126  {
1127  get_dat2(self, other);
1128 
1129  if (f_zero_p(adat->num) && f_zero_p(bdat->num))
1130  return Qtrue;
1131 
1132  return f_boolcast(f_eqeq_p(adat->num, bdat->num) &&
1133  f_eqeq_p(adat->den, bdat->den));
1134  }
1135  default:
1136  return f_eqeq_p(other, self);
1137  }
1138 }
1139 
1140 /* :nodoc: */
1141 static VALUE
1143 {
1144  switch (TYPE(other)) {
1145  case T_FIXNUM:
1146  case T_BIGNUM:
1147  return rb_assoc_new(f_rational_new_bang1(CLASS_OF(self), other), self);
1148  case T_FLOAT:
1149  return rb_assoc_new(other, f_to_f(self));
1150  case T_RATIONAL:
1151  return rb_assoc_new(other, self);
1152  case T_COMPLEX:
1153  if (k_exact_zero_p(RCOMPLEX(other)->imag))
1155  (CLASS_OF(self), RCOMPLEX(other)->real), self);
1156  else
1157  return rb_assoc_new(other, rb_Complex(self, INT2FIX(0)));
1158  }
1159 
1160  rb_raise(rb_eTypeError, "%s can't be coerced into %s",
1161  rb_obj_classname(other), rb_obj_classname(self));
1162  return Qnil;
1163 }
1164 
1165 #if 0
1166 /* :nodoc: */
1167 static VALUE
1168 nurat_idiv(VALUE self, VALUE other)
1169 {
1170  return f_idiv(self, other);
1171 }
1172 
1173 /* :nodoc: */
1174 static VALUE
1175 nurat_quot(VALUE self, VALUE other)
1176 {
1177  return f_truncate(f_div(self, other));
1178 }
1179 
1180 /* :nodoc: */
1181 static VALUE
1182 nurat_quotrem(VALUE self, VALUE other)
1183 {
1184  VALUE val = f_truncate(f_div(self, other));
1185  return rb_assoc_new(val, f_sub(self, f_mul(other, val)));
1186 }
1187 #endif
1188 
1189 #if 0
1190 /* :nodoc: */
1191 static VALUE
1192 nurat_true(VALUE self)
1193 {
1194  return Qtrue;
1195 }
1196 #endif
1197 
1198 static VALUE
1200 {
1201  get_dat1(self);
1202  return f_idiv(dat->num, dat->den);
1203 }
1204 
1205 static VALUE
1207 {
1208  get_dat1(self);
1209  return f_negate(f_idiv(f_negate(dat->num), dat->den));
1210 }
1211 
1212 /*
1213  * call-seq:
1214  * rat.to_i -> integer
1215  *
1216  * Returns the truncated value as an integer.
1217  *
1218  * Equivalent to
1219  * rat.truncate.
1220  *
1221  * Rational(2, 3).to_i #=> 0
1222  * Rational(3).to_i #=> 3
1223  * Rational(300.6).to_i #=> 300
1224  * Rational(98,71).to_i #=> 1
1225  * Rational(-30,2).to_i #=> -15
1226  */
1227 static VALUE
1229 {
1230  get_dat1(self);
1231  if (f_negative_p(dat->num))
1232  return f_negate(f_idiv(f_negate(dat->num), dat->den));
1233  return f_idiv(dat->num, dat->den);
1234 }
1235 
1236 static VALUE
1238 {
1239  VALUE num, den, neg;
1240 
1241  get_dat1(self);
1242 
1243  num = dat->num;
1244  den = dat->den;
1245  neg = f_negative_p(num);
1246 
1247  if (neg)
1248  num = f_negate(num);
1249 
1250  num = f_add(f_mul(num, TWO), den);
1251  den = f_mul(den, TWO);
1252  num = f_idiv(num, den);
1253 
1254  if (neg)
1255  num = f_negate(num);
1256 
1257  return num;
1258 }
1259 
1260 static VALUE
1262 {
1263  VALUE n, b, s;
1264 
1265  if (argc == 0)
1266  return (*func)(self);
1267 
1268  rb_scan_args(argc, argv, "01", &n);
1269 
1270  if (!k_integer_p(n))
1271  rb_raise(rb_eTypeError, "not an integer");
1272 
1273  b = f_expt10(n);
1274  s = f_mul(self, b);
1275 
1276  if (k_float_p(s)) {
1277  if (f_lt_p(n, ZERO))
1278  return ZERO;
1279  return self;
1280  }
1281 
1282  s = (*func)(s);
1283 
1284  s = f_div(f_rational_new_bang1(CLASS_OF(self), s), b);
1285 
1286  if (f_lt_p(n, ONE))
1287  s = f_to_i(s);
1288 
1289  return s;
1290 }
1291 
1292 /*
1293  * call-seq:
1294  * rat.floor -> integer
1295  * rat.floor(precision=0) -> rational
1296  *
1297  * Returns the truncated value (toward negative infinity).
1298  *
1299  * Rational(3).floor #=> 3
1300  * Rational(2, 3).floor #=> 0
1301  * Rational(-3, 2).floor #=> -1
1302  *
1303  * decimal - 1 2 3 . 4 5 6
1304  * ^ ^ ^ ^ ^ ^
1305  * precision -3 -2 -1 0 +1 +2
1306  *
1307  * '%f' % Rational('-123.456').floor(+1) #=> "-123.500000"
1308  * '%f' % Rational('-123.456').floor(-1) #=> "-130.000000"
1309  */
1310 static VALUE
1311 nurat_floor_n(int argc, VALUE *argv, VALUE self)
1312 {
1313  return f_round_common(argc, argv, self, nurat_floor);
1314 }
1315 
1316 /*
1317  * call-seq:
1318  * rat.ceil -> integer
1319  * rat.ceil(precision=0) -> rational
1320  *
1321  * Returns the truncated value (toward positive infinity).
1322  *
1323  * Rational(3).ceil #=> 3
1324  * Rational(2, 3).ceil #=> 1
1325  * Rational(-3, 2).ceil #=> -1
1326  *
1327  * decimal - 1 2 3 . 4 5 6
1328  * ^ ^ ^ ^ ^ ^
1329  * precision -3 -2 -1 0 +1 +2
1330  *
1331  * '%f' % Rational('-123.456').ceil(+1) #=> "-123.400000"
1332  * '%f' % Rational('-123.456').ceil(-1) #=> "-120.000000"
1333  */
1334 static VALUE
1335 nurat_ceil_n(int argc, VALUE *argv, VALUE self)
1336 {
1337  return f_round_common(argc, argv, self, nurat_ceil);
1338 }
1339 
1340 /*
1341  * call-seq:
1342  * rat.truncate -> integer
1343  * rat.truncate(precision=0) -> rational
1344  *
1345  * Returns the truncated value (toward zero).
1346  *
1347  * Rational(3).truncate #=> 3
1348  * Rational(2, 3).truncate #=> 0
1349  * Rational(-3, 2).truncate #=> -1
1350  *
1351  * decimal - 1 2 3 . 4 5 6
1352  * ^ ^ ^ ^ ^ ^
1353  * precision -3 -2 -1 0 +1 +2
1354  *
1355  * '%f' % Rational('-123.456').truncate(+1) #=> "-123.400000"
1356  * '%f' % Rational('-123.456').truncate(-1) #=> "-120.000000"
1357  */
1358 static VALUE
1359 nurat_truncate_n(int argc, VALUE *argv, VALUE self)
1360 {
1361  return f_round_common(argc, argv, self, nurat_truncate);
1362 }
1363 
1364 /*
1365  * call-seq:
1366  * rat.round -> integer
1367  * rat.round(precision=0) -> rational
1368  *
1369  * Returns the truncated value (toward the nearest integer;
1370  * 0.5 => 1; -0.5 => -1).
1371  *
1372  * Rational(3).round #=> 3
1373  * Rational(2, 3).round #=> 1
1374  * Rational(-3, 2).round #=> -2
1375  *
1376  * decimal - 1 2 3 . 4 5 6
1377  * ^ ^ ^ ^ ^ ^
1378  * precision -3 -2 -1 0 +1 +2
1379  *
1380  * '%f' % Rational('-123.456').round(+1) #=> "-123.500000"
1381  * '%f' % Rational('-123.456').round(-1) #=> "-120.000000"
1382  */
1383 static VALUE
1384 nurat_round_n(int argc, VALUE *argv, VALUE self)
1385 {
1386  return f_round_common(argc, argv, self, nurat_round);
1387 }
1388 
1389 /*
1390  * call-seq:
1391  * rat.to_f -> float
1392  *
1393  * Return the value as a float.
1394  *
1395  * Rational(2).to_f #=> 2.0
1396  * Rational(9, 4).to_f #=> 2.25
1397  * Rational(-3, 4).to_f #=> -0.75
1398  * Rational(20, 3).to_f #=> 6.666666666666667
1399  */
1400 static VALUE
1402 {
1403  get_dat1(self);
1404  return f_fdiv(dat->num, dat->den);
1405 }
1406 
1407 /*
1408  * call-seq:
1409  * rat.to_r -> self
1410  *
1411  * Returns self.
1412  *
1413  * Rational(2).to_r #=> (2/1)
1414  * Rational(-8, 6).to_r #=> (-4/3)
1415  */
1416 static VALUE
1418 {
1419  return self;
1420 }
1421 
1422 #define id_ceil rb_intern("ceil")
1423 #define f_ceil(x) rb_funcall((x), id_ceil, 0)
1424 
1425 #define id_quo rb_intern("quo")
1426 #define f_quo(x,y) rb_funcall((x), id_quo, 1, (y))
1427 
1428 #define f_reciprocal(x) f_quo(ONE, (x))
1429 
1430 /*
1431  The algorithm here is the method described in CLISP. Bruno Haible has
1432  graciously given permission to use this algorithm. He says, "You can use
1433  it, if you present the following explanation of the algorithm."
1434 
1435  Algorithm (recursively presented):
1436  If x is a rational number, return x.
1437  If x = 0.0, return 0.
1438  If x < 0.0, return (- (rationalize (- x))).
1439  If x > 0.0:
1440  Call (integer-decode-float x). It returns a m,e,s=1 (mantissa,
1441  exponent, sign).
1442  If m = 0 or e >= 0: return x = m*2^e.
1443  Search a rational number between a = (m-1/2)*2^e and b = (m+1/2)*2^e
1444  with smallest possible numerator and denominator.
1445  Note 1: If m is a power of 2, we ought to take a = (m-1/4)*2^e.
1446  But in this case the result will be x itself anyway, regardless of
1447  the choice of a. Therefore we can simply ignore this case.
1448  Note 2: At first, we need to consider the closed interval [a,b].
1449  but since a and b have the denominator 2^(|e|+1) whereas x itself
1450  has a denominator <= 2^|e|, we can restrict the search to the open
1451  interval (a,b).
1452  So, for given a and b (0 < a < b) we are searching a rational number
1453  y with a <= y <= b.
1454  Recursive algorithm fraction_between(a,b):
1455  c := (ceiling a)
1456  if c < b
1457  then return c ; because a <= c < b, c integer
1458  else
1459  ; a is not integer (otherwise we would have had c = a < b)
1460  k := c-1 ; k = floor(a), k < a < b <= k+1
1461  return y = k + 1/fraction_between(1/(b-k), 1/(a-k))
1462  ; note 1 <= 1/(b-k) < 1/(a-k)
1463 
1464  You can see that we are actually computing a continued fraction expansion.
1465 
1466  Algorithm (iterative):
1467  If x is rational, return x.
1468  Call (integer-decode-float x). It returns a m,e,s (mantissa,
1469  exponent, sign).
1470  If m = 0 or e >= 0, return m*2^e*s. (This includes the case x = 0.0.)
1471  Create rational numbers a := (2*m-1)*2^(e-1) and b := (2*m+1)*2^(e-1)
1472  (positive and already in lowest terms because the denominator is a
1473  power of two and the numerator is odd).
1474  Start a continued fraction expansion
1475  p[-1] := 0, p[0] := 1, q[-1] := 1, q[0] := 0, i := 0.
1476  Loop
1477  c := (ceiling a)
1478  if c >= b
1479  then k := c-1, partial_quotient(k), (a,b) := (1/(b-k),1/(a-k)),
1480  goto Loop
1481  finally partial_quotient(c).
1482  Here partial_quotient(c) denotes the iteration
1483  i := i+1, p[i] := c*p[i-1]+p[i-2], q[i] := c*q[i-1]+q[i-2].
1484  At the end, return s * (p[i]/q[i]).
1485  This rational number is already in lowest terms because
1486  p[i]*q[i-1]-p[i-1]*q[i] = (-1)^i.
1487 */
1488 
1489 static void
1491 {
1492  VALUE c, k, t, p0, p1, p2, q0, q1, q2;
1493 
1494  p0 = ZERO;
1495  p1 = ONE;
1496  q0 = ONE;
1497  q1 = ZERO;
1498 
1499  while (1) {
1500  c = f_ceil(a);
1501  if (f_lt_p(c, b))
1502  break;
1503  k = f_sub(c, ONE);
1504  p2 = f_add(f_mul(k, p1), p0);
1505  q2 = f_add(f_mul(k, q1), q0);
1506  t = f_reciprocal(f_sub(b, k));
1507  b = f_reciprocal(f_sub(a, k));
1508  a = t;
1509  p0 = p1;
1510  q0 = q1;
1511  p1 = p2;
1512  q1 = q2;
1513  }
1514  *p = f_add(f_mul(c, p1), p0);
1515  *q = f_add(f_mul(c, q1), q0);
1516 }
1517 
1518 /*
1519  * call-seq:
1520  * rat.rationalize -> self
1521  * rat.rationalize(eps) -> rational
1522  *
1523  * Returns a simpler approximation of the value if the optional
1524  * argument eps is given (rat-|eps| <= result <= rat+|eps|), self
1525  * otherwise.
1526  *
1527  * r = Rational(5033165, 16777216)
1528  * r.rationalize #=> (5033165/16777216)
1529  * r.rationalize(Rational('0.01')) #=> (3/10)
1530  * r.rationalize(Rational('0.1')) #=> (1/3)
1531  */
1532 static VALUE
1533 nurat_rationalize(int argc, VALUE *argv, VALUE self)
1534 {
1535  VALUE e, a, b, p, q;
1536 
1537  if (argc == 0)
1538  return self;
1539 
1540  if (f_negative_p(self))
1541  return f_negate(nurat_rationalize(argc, argv, f_abs(self)));
1542 
1543  rb_scan_args(argc, argv, "01", &e);
1544  e = f_abs(e);
1545  a = f_sub(self, e);
1546  b = f_add(self, e);
1547 
1548  if (f_eqeq_p(a, b))
1549  return self;
1550 
1551  nurat_rationalize_internal(a, b, &p, &q);
1552  return f_rational_new2(CLASS_OF(self), p, q);
1553 }
1554 
1555 /* :nodoc: */
1556 static VALUE
1558 {
1559  st_index_t v, h[2];
1560  VALUE n;
1561 
1562  get_dat1(self);
1563  n = rb_hash(dat->num);
1564  h[0] = NUM2LONG(n);
1565  n = rb_hash(dat->den);
1566  h[1] = NUM2LONG(n);
1567  v = rb_memhash(h, sizeof(h));
1568  return LONG2FIX(v);
1569 }
1570 
1571 static VALUE
1573 {
1574  VALUE s;
1575  get_dat1(self);
1576 
1577  s = (*func)(dat->num);
1578  rb_str_cat2(s, "/");
1579  rb_str_concat(s, (*func)(dat->den));
1580 
1581  return s;
1582 }
1583 
1584 /*
1585  * call-seq:
1586  * rat.to_s -> string
1587  *
1588  * Returns the value as a string.
1589  *
1590  * Rational(2).to_s #=> "2/1"
1591  * Rational(-8, 6).to_s #=> "-4/3"
1592  * Rational('1/2').to_s #=> "1/2"
1593  */
1594 static VALUE
1596 {
1597  return f_format(self, f_to_s);
1598 }
1599 
1600 /*
1601  * call-seq:
1602  * rat.inspect -> string
1603  *
1604  * Returns the value as a string for inspection.
1605  *
1606  * Rational(2).inspect #=> "(2/1)"
1607  * Rational(-8, 6).inspect #=> "(-4/3)"
1608  * Rational('1/2').inspect #=> "(1/2)"
1609  */
1610 static VALUE
1612 {
1613  VALUE s;
1614 
1615  s = rb_usascii_str_new2("(");
1616  rb_str_concat(s, f_format(self, f_inspect));
1617  rb_str_cat2(s, ")");
1618 
1619  return s;
1620 }
1621 
1622 /* :nodoc: */
1623 static VALUE
1625 {
1626  return self;
1627 }
1628 
1629 /* :nodoc: */
1630 static VALUE
1632 {
1633  get_dat1(self);
1634 
1635  dat->num = rb_ivar_get(a, id_i_num);
1636  dat->den = rb_ivar_get(a, id_i_den);
1637 
1638  return self;
1639 }
1640 
1641 /* :nodoc: */
1642 static VALUE
1644 {
1645  VALUE a;
1646  get_dat1(self);
1647 
1648  a = rb_assoc_new(dat->num, dat->den);
1649  rb_copy_generic_ivar(a, self);
1650  return a;
1651 }
1652 
1653 /* :nodoc: */
1654 static VALUE
1656 {
1657  rb_check_frozen(self);
1658  rb_check_trusted(self);
1659 
1660  Check_Type(a, T_ARRAY);
1661  if (RARRAY_LEN(a) != 2)
1662  rb_raise(rb_eArgError, "marshaled rational must have an array whose length is 2 but %ld", RARRAY_LEN(a));
1663  if (f_zero_p(RARRAY_PTR(a)[1]))
1664  rb_raise_zerodiv();
1665 
1666  rb_ivar_set(self, id_i_num, RARRAY_PTR(a)[0]);
1667  rb_ivar_set(self, id_i_den, RARRAY_PTR(a)[1]);
1668 
1669  return self;
1670 }
1671 
1672 /* --- */
1673 
1674 VALUE
1676 {
1677  get_dat1(x);
1678  return f_rational_new_no_reduce2(CLASS_OF(x), dat->den, dat->num);
1679 }
1680 
1681 /*
1682  * call-seq:
1683  * int.gcd(int2) -> integer
1684  *
1685  * Returns the greatest common divisor (always positive). 0.gcd(x)
1686  * and x.gcd(0) return abs(x).
1687  *
1688  * 2.gcd(2) #=> 2
1689  * 3.gcd(-7) #=> 1
1690  * ((1<<31)-1).gcd((1<<61)-1) #=> 1
1691  */
1692 VALUE
1693 rb_gcd(VALUE self, VALUE other)
1694 {
1695  other = nurat_int_value(other);
1696  return f_gcd(self, other);
1697 }
1698 
1699 /*
1700  * call-seq:
1701  * int.lcm(int2) -> integer
1702  *
1703  * Returns the least common multiple (always positive). 0.lcm(x) and
1704  * x.lcm(0) return zero.
1705  *
1706  * 2.lcm(2) #=> 2
1707  * 3.lcm(-7) #=> 21
1708  * ((1<<31)-1).lcm((1<<61)-1) #=> 4951760154835678088235319297
1709  */
1710 VALUE
1711 rb_lcm(VALUE self, VALUE other)
1712 {
1713  other = nurat_int_value(other);
1714  return f_lcm(self, other);
1715 }
1716 
1717 /*
1718  * call-seq:
1719  * int.gcdlcm(int2) -> array
1720  *
1721  * Returns an array; [int.gcd(int2), int.lcm(int2)].
1722  *
1723  * 2.gcdlcm(2) #=> [2, 2]
1724  * 3.gcdlcm(-7) #=> [1, 21]
1725  * ((1<<31)-1).gcdlcm((1<<61)-1) #=> [1, 4951760154835678088235319297]
1726  */
1727 VALUE
1728 rb_gcdlcm(VALUE self, VALUE other)
1729 {
1730  other = nurat_int_value(other);
1731  return rb_assoc_new(f_gcd(self, other), f_lcm(self, other));
1732 }
1733 
1734 VALUE
1736 {
1737  return nurat_s_new_internal(rb_cRational, x, y);
1738 }
1739 
1740 VALUE
1742 {
1744 }
1745 
1746 static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass);
1747 
1748 VALUE
1750 {
1751  VALUE a[2];
1752  a[0] = x;
1753  a[1] = y;
1754  return nurat_s_convert(2, a, rb_cRational);
1755 }
1756 
1757 #define id_numerator rb_intern("numerator")
1758 #define f_numerator(x) rb_funcall((x), id_numerator, 0)
1759 
1760 #define id_denominator rb_intern("denominator")
1761 #define f_denominator(x) rb_funcall((x), id_denominator, 0)
1762 
1763 #define id_to_r rb_intern("to_r")
1764 #define f_to_r(x) rb_funcall((x), id_to_r, 0)
1765 
1766 /*
1767  * call-seq:
1768  * num.numerator -> integer
1769  *
1770  * Returns the numerator.
1771  */
1772 static VALUE
1774 {
1775  return f_numerator(f_to_r(self));
1776 }
1777 
1778 /*
1779  * call-seq:
1780  * num.denominator -> integer
1781  *
1782  * Returns the denominator (always positive).
1783  */
1784 static VALUE
1786 {
1787  return f_denominator(f_to_r(self));
1788 }
1789 
1790 /*
1791  * call-seq:
1792  * int.numerator -> self
1793  *
1794  * Returns self.
1795  */
1796 static VALUE
1798 {
1799  return self;
1800 }
1801 
1802 /*
1803  * call-seq:
1804  * int.denominator -> 1
1805  *
1806  * Returns 1.
1807  */
1808 static VALUE
1810 {
1811  return INT2FIX(1);
1812 }
1813 
1814 /*
1815  * call-seq:
1816  * flo.numerator -> integer
1817  *
1818  * Returns the numerator. The result is machine dependent.
1819  *
1820  * n = 0.3.numerator #=> 5404319552844595
1821  * d = 0.3.denominator #=> 18014398509481984
1822  * n.fdiv(d) #=> 0.3
1823  */
1824 static VALUE
1826 {
1827  double d = RFLOAT_VALUE(self);
1828  if (isinf(d) || isnan(d))
1829  return self;
1830  return rb_call_super(0, 0);
1831 }
1832 
1833 /*
1834  * call-seq:
1835  * flo.denominator -> integer
1836  *
1837  * Returns the denominator (always positive). The result is machine
1838  * dependent.
1839  *
1840  * See numerator.
1841  */
1842 static VALUE
1844 {
1845  double d = RFLOAT_VALUE(self);
1846  if (isinf(d) || isnan(d))
1847  return INT2FIX(1);
1848  return rb_call_super(0, 0);
1849 }
1850 
1851 /*
1852  * call-seq:
1853  * nil.to_r -> (0/1)
1854  *
1855  * Returns zero as a rational.
1856  */
1857 static VALUE
1859 {
1860  return rb_rational_new1(INT2FIX(0));
1861 }
1862 
1863 /*
1864  * call-seq:
1865  * nil.rationalize([eps]) -> (0/1)
1866  *
1867  * Returns zero as a rational. The optional argument eps is always
1868  * ignored.
1869  */
1870 static VALUE
1871 nilclass_rationalize(int argc, VALUE *argv, VALUE self)
1872 {
1873  rb_scan_args(argc, argv, "01", NULL);
1874  return nilclass_to_r(self);
1875 }
1876 
1877 /*
1878  * call-seq:
1879  * int.to_r -> rational
1880  *
1881  * Returns the value as a rational.
1882  *
1883  * 1.to_r #=> (1/1)
1884  * (1<<64).to_r #=> (18446744073709551616/1)
1885  */
1886 static VALUE
1888 {
1889  return rb_rational_new1(self);
1890 }
1891 
1892 /*
1893  * call-seq:
1894  * int.rationalize([eps]) -> rational
1895  *
1896  * Returns the value as a rational. The optional argument eps is
1897  * always ignored.
1898  */
1899 static VALUE
1900 integer_rationalize(int argc, VALUE *argv, VALUE self)
1901 {
1902  rb_scan_args(argc, argv, "01", NULL);
1903  return integer_to_r(self);
1904 }
1905 
1906 static void
1908 {
1909  double f;
1910  int n;
1911 
1912  f = frexp(RFLOAT_VALUE(self), &n);
1913  f = ldexp(f, DBL_MANT_DIG);
1914  n -= DBL_MANT_DIG;
1915  *rf = rb_dbl2big(f);
1916  *rn = INT2FIX(n);
1917 }
1918 
1919 #if 0
1920 static VALUE
1921 float_decode(VALUE self)
1922 {
1923  VALUE f, n;
1924 
1925  float_decode_internal(self, &f, &n);
1926  return rb_assoc_new(f, n);
1927 }
1928 #endif
1929 
1930 #define id_lshift rb_intern("<<")
1931 #define f_lshift(x,n) rb_funcall((x), id_lshift, 1, (n))
1932 
1933 /*
1934  * call-seq:
1935  * flt.to_r -> rational
1936  *
1937  * Returns the value as a rational.
1938  *
1939  * NOTE: 0.3.to_r isn't the same as '0.3'.to_r. The latter is
1940  * equivalent to '3/10'.to_r, but the former isn't so.
1941  *
1942  * 2.0.to_r #=> (2/1)
1943  * 2.5.to_r #=> (5/2)
1944  * -0.75.to_r #=> (-3/4)
1945  * 0.0.to_r #=> (0/1)
1946  *
1947  * See rationalize.
1948  */
1949 static VALUE
1951 {
1952  VALUE f, n;
1953 
1954  float_decode_internal(self, &f, &n);
1955 #if FLT_RADIX == 2
1956  {
1957  long ln = FIX2LONG(n);
1958 
1959  if (ln == 0)
1960  return f_to_r(f);
1961  if (ln > 0)
1962  return f_to_r(f_lshift(f, n));
1963  ln = -ln;
1964  return rb_rational_new2(f, f_lshift(ONE, INT2FIX(ln)));
1965  }
1966 #else
1967  return f_to_r(f_mul(f, f_expt(INT2FIX(FLT_RADIX), n)));
1968 #endif
1969 }
1970 
1971 /*
1972  * call-seq:
1973  * flt.rationalize([eps]) -> rational
1974  *
1975  * Returns a simpler approximation of the value (flt-|eps| <= result
1976  * <= flt+|eps|). if the optional eps is not given, it will be chosen
1977  * automatically.
1978  *
1979  * 0.3.rationalize #=> (3/10)
1980  * 1.333.rationalize #=> (1333/1000)
1981  * 1.333.rationalize(0.01) #=> (4/3)
1982  *
1983  * See to_r.
1984  */
1985 static VALUE
1986 float_rationalize(int argc, VALUE *argv, VALUE self)
1987 {
1988  VALUE e, a, b, p, q;
1989 
1990  if (f_negative_p(self))
1991  return f_negate(float_rationalize(argc, argv, f_abs(self)));
1992 
1993  rb_scan_args(argc, argv, "01", &e);
1994 
1995  if (argc != 0) {
1996  e = f_abs(e);
1997  a = f_sub(self, e);
1998  b = f_add(self, e);
1999  }
2000  else {
2001  VALUE f, n;
2002 
2003  float_decode_internal(self, &f, &n);
2004  if (f_zero_p(f) || f_positive_p(n))
2005  return rb_rational_new1(f_lshift(f, n));
2006 
2007 #if FLT_RADIX == 2
2008  {
2009  VALUE two_times_f, den;
2010 
2011  two_times_f = f_mul(TWO, f);
2012  den = f_lshift(ONE, f_sub(ONE, n));
2013 
2014  a = rb_rational_new2(f_sub(two_times_f, ONE), den);
2015  b = rb_rational_new2(f_add(two_times_f, ONE), den);
2016  }
2017 #else
2018  {
2019  VALUE radix_times_f, den;
2020 
2021  radix_times_f = f_mul(INT2FIX(FLT_RADIX), f);
2022  den = f_expt(INT2FIX(FLT_RADIX), f_sub(ONE, n));
2023 
2024  a = rb_rational_new2(f_sub(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
2025  b = rb_rational_new2(f_add(radix_times_f, INT2FIX(FLT_RADIX - 1)), den);
2026  }
2027 #endif
2028  }
2029 
2030  if (f_eqeq_p(a, b))
2031  return f_to_r(self);
2032 
2033  nurat_rationalize_internal(a, b, &p, &q);
2034  return rb_rational_new2(p, q);
2035 }
2036 
2037 #include <ctype.h>
2038 
2039 inline static int
2040 issign(int c)
2041 {
2042  return (c == '-' || c == '+');
2043 }
2044 
2045 static int
2046 read_sign(const char **s)
2047 {
2048  int sign = '?';
2049 
2050  if (issign(**s)) {
2051  sign = **s;
2052  (*s)++;
2053  }
2054  return sign;
2055 }
2056 
2057 inline static int
2059 {
2060  return isdigit((unsigned char)c);
2061 }
2062 
2063 static int
2064 read_digits(const char **s, int strict,
2065  VALUE *num, int *count)
2066 {
2067  char *b, *bb;
2068  int us = 1, ret = 1;
2069 
2070  if (!isdecimal(**s)) {
2071  *num = ZERO;
2072  return 0;
2073  }
2074 
2075  bb = b = ALLOCA_N(char, strlen(*s) + 1);
2076 
2077  while (isdecimal(**s) || **s == '_') {
2078  if (**s == '_') {
2079  if (strict) {
2080  if (us) {
2081  ret = 0;
2082  goto conv;
2083  }
2084  }
2085  us = 1;
2086  }
2087  else {
2088  if (count)
2089  (*count)++;
2090  *b++ = **s;
2091  us = 0;
2092  }
2093  (*s)++;
2094  }
2095  if (us)
2096  do {
2097  (*s)--;
2098  } while (**s == '_');
2099  conv:
2100  *b = '\0';
2101  *num = rb_cstr_to_inum(bb, 10, 0);
2102  return ret;
2103 }
2104 
2105 inline static int
2107 {
2108  return (c == 'e' || c == 'E');
2109 }
2110 
2111 static int
2112 read_num(const char **s, int numsign, int strict,
2113  VALUE *num)
2114 {
2115  VALUE ip, fp, exp;
2116 
2117  *num = rb_rational_new2(ZERO, ONE);
2118  exp = Qnil;
2119 
2120  if (**s != '.') {
2121  if (!read_digits(s, strict, &ip, NULL))
2122  return 0;
2123  *num = rb_rational_new2(ip, ONE);
2124  }
2125 
2126  if (**s == '.') {
2127  int count = 0;
2128 
2129  (*s)++;
2130  if (!read_digits(s, strict, &fp, &count))
2131  return 0;
2132  {
2133  VALUE l = f_expt10(INT2NUM(count));
2134  *num = f_mul(*num, l);
2135  *num = f_add(*num, fp);
2136  *num = f_div(*num, l);
2137  }
2138  }
2139 
2140  if (islettere(**s)) {
2141  int expsign;
2142 
2143  (*s)++;
2144  expsign = read_sign(s);
2145  if (!read_digits(s, strict, &exp, NULL))
2146  return 0;
2147  if (expsign == '-')
2148  exp = f_negate(exp);
2149  }
2150 
2151  if (numsign == '-')
2152  *num = f_negate(*num);
2153  if (!NIL_P(exp)) {
2154  VALUE l = f_expt10(exp);
2155  *num = f_mul(*num, l);
2156  }
2157  return 1;
2158 }
2159 
2160 inline static int
2161 read_den(const char **s, int strict,
2162  VALUE *num)
2163 {
2164  if (!read_digits(s, strict, num, NULL))
2165  return 0;
2166  return 1;
2167 }
2168 
2169 static int
2170 read_rat_nos(const char **s, int sign, int strict,
2171  VALUE *num)
2172 {
2173  VALUE den;
2174 
2175  if (!read_num(s, sign, strict, num))
2176  return 0;
2177  if (**s == '/') {
2178  (*s)++;
2179  if (!read_den(s, strict, &den))
2180  return 0;
2181  if (!(FIXNUM_P(den) && FIX2LONG(den) == 1))
2182  *num = f_div(*num, den);
2183  }
2184  return 1;
2185 }
2186 
2187 static int
2188 read_rat(const char **s, int strict,
2189  VALUE *num)
2190 {
2191  int sign;
2192 
2193  sign = read_sign(s);
2194  if (!read_rat_nos(s, sign, strict, num))
2195  return 0;
2196  return 1;
2197 }
2198 
2199 inline static void
2200 skip_ws(const char **s)
2201 {
2202  while (isspace((unsigned char)**s))
2203  (*s)++;
2204 }
2205 
2206 static int
2207 parse_rat(const char *s, int strict,
2208  VALUE *num)
2209 {
2210  skip_ws(&s);
2211  if (!read_rat(&s, strict, num))
2212  return 0;
2213  skip_ws(&s);
2214 
2215  if (strict)
2216  if (*s != '\0')
2217  return 0;
2218  return 1;
2219 }
2220 
2221 static VALUE
2223 {
2224  char *s;
2225  VALUE num;
2226 
2227  rb_must_asciicompat(self);
2228 
2229  s = RSTRING_PTR(self);
2230 
2231  if (!s || memchr(s, '\0', RSTRING_LEN(self)))
2232  rb_raise(rb_eArgError, "string contains null byte");
2233 
2234  if (s && s[RSTRING_LEN(self)]) {
2235  rb_str_modify(self);
2236  s = RSTRING_PTR(self);
2237  s[RSTRING_LEN(self)] = '\0';
2238  }
2239 
2240  if (!s)
2241  s = (char *)"";
2242 
2243  if (!parse_rat(s, 1, &num)) {
2244  VALUE ins = f_inspect(self);
2245  rb_raise(rb_eArgError, "invalid value for convert(): %s",
2246  StringValuePtr(ins));
2247  }
2248 
2249  if (RB_TYPE_P(num, T_FLOAT))
2250  rb_raise(rb_eFloatDomainError, "Infinity");
2251  return num;
2252 }
2253 
2254 /*
2255  * call-seq:
2256  * str.to_r -> rational
2257  *
2258  * Returns a rational which denotes the string form. The parser
2259  * ignores leading whitespaces and trailing garbage. Any digit
2260  * sequences can be separated by an underscore. Returns zero for null
2261  * or garbage string.
2262  *
2263  * NOTE: '0.3'.to_r isn't the same as 0.3.to_r. The former is
2264  * equivalent to '3/10'.to_r, but the latter isn't so.
2265  *
2266  * ' 2 '.to_r #=> (2/1)
2267  * '300/2'.to_r #=> (150/1)
2268  * '-9.2'.to_r #=> (-46/5)
2269  * '-9.2e2'.to_r #=> (-920/1)
2270  * '1_234_567'.to_r #=> (1234567/1)
2271  * '21 june 09'.to_r #=> (21/1)
2272  * '21/06/09'.to_r #=> (7/2)
2273  * 'bwv 1079'.to_r #=> (0/1)
2274  *
2275  * See Kernel.Rational.
2276  */
2277 static VALUE
2279 {
2280  char *s;
2281  VALUE num;
2282 
2283  rb_must_asciicompat(self);
2284 
2285  s = RSTRING_PTR(self);
2286 
2287  if (s && s[RSTRING_LEN(self)]) {
2288  rb_str_modify(self);
2289  s = RSTRING_PTR(self);
2290  s[RSTRING_LEN(self)] = '\0';
2291  }
2292 
2293  if (!s)
2294  s = (char *)"";
2295 
2296  (void)parse_rat(s, 0, &num);
2297 
2298  if (RB_TYPE_P(num, T_FLOAT))
2299  rb_raise(rb_eFloatDomainError, "Infinity");
2300  return num;
2301 }
2302 
2303 VALUE
2304 rb_cstr_to_rat(const char *s, int strict) /* for complex's internal */
2305 {
2306  VALUE num;
2307 
2308  (void)parse_rat(s, strict, &num);
2309 
2310  if (RB_TYPE_P(num, T_FLOAT))
2311  rb_raise(rb_eFloatDomainError, "Infinity");
2312  return num;
2313 }
2314 
2315 static VALUE
2317 {
2318  VALUE a1, a2, backref;
2319 
2320  rb_scan_args(argc, argv, "11", &a1, &a2);
2321 
2322  if (NIL_P(a1) || (argc == 2 && NIL_P(a2)))
2323  rb_raise(rb_eTypeError, "can't convert nil into Rational");
2324 
2325  switch (TYPE(a1)) {
2326  case T_COMPLEX:
2327  if (k_exact_zero_p(RCOMPLEX(a1)->imag))
2328  a1 = RCOMPLEX(a1)->real;
2329  }
2330 
2331  switch (TYPE(a2)) {
2332  case T_COMPLEX:
2333  if (k_exact_zero_p(RCOMPLEX(a2)->imag))
2334  a2 = RCOMPLEX(a2)->real;
2335  }
2336 
2337  backref = rb_backref_get();
2338  rb_match_busy(backref);
2339 
2340  switch (TYPE(a1)) {
2341  case T_FIXNUM:
2342  case T_BIGNUM:
2343  break;
2344  case T_FLOAT:
2345  a1 = f_to_r(a1);
2346  break;
2347  case T_STRING:
2348  a1 = string_to_r_strict(a1);
2349  break;
2350  }
2351 
2352  switch (TYPE(a2)) {
2353  case T_FIXNUM:
2354  case T_BIGNUM:
2355  break;
2356  case T_FLOAT:
2357  a2 = f_to_r(a2);
2358  break;
2359  case T_STRING:
2360  a2 = string_to_r_strict(a2);
2361  break;
2362  }
2363 
2364  rb_backref_set(backref);
2365 
2366  switch (TYPE(a1)) {
2367  case T_RATIONAL:
2368  if (argc == 1 || (k_exact_one_p(a2)))
2369  return a1;
2370  }
2371 
2372  if (argc == 1) {
2373  if (!(k_numeric_p(a1) && k_integer_p(a1)))
2374  return rb_convert_type(a1, T_RATIONAL, "Rational", "to_r");
2375  }
2376  else {
2377  if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
2378  (!f_integer_p(a1) || !f_integer_p(a2)))
2379  return f_div(a1, a2);
2380  }
2381 
2382  {
2383  VALUE argv2[2];
2384  argv2[0] = a1;
2385  argv2[1] = a2;
2386  return nurat_s_new(argc, argv2, klass);
2387  }
2388 }
2389 
2390 /*
2391  * A rational number can be represented as a paired integer number;
2392  * a/b (b>0). Where a is numerator and b is denominator. Integer a
2393  * equals rational a/1 mathematically.
2394  *
2395  * In ruby, you can create rational object with Rational, to_r or
2396  * rationalize method. The return values will be irreducible.
2397  *
2398  * Rational(1) #=> (1/1)
2399  * Rational(2, 3) #=> (2/3)
2400  * Rational(4, -6) #=> (-2/3)
2401  * 3.to_r #=> (3/1)
2402  *
2403  * You can also create rational object from floating-point numbers or
2404  * strings.
2405  *
2406  * Rational(0.3) #=> (5404319552844595/18014398509481984)
2407  * Rational('0.3') #=> (3/10)
2408  * Rational('2/3') #=> (2/3)
2409  *
2410  * 0.3.to_r #=> (5404319552844595/18014398509481984)
2411  * '0.3'.to_r #=> (3/10)
2412  * '2/3'.to_r #=> (2/3)
2413  * 0.3.rationalize #=> (3/10)
2414  *
2415  * A rational object is an exact number, which helps you to write
2416  * program without any rounding errors.
2417  *
2418  * 10.times.inject(0){|t,| t + 0.1} #=> 0.9999999999999999
2419  * 10.times.inject(0){|t,| t + Rational('0.1')} #=> (1/1)
2420  *
2421  * However, when an expression has inexact factor (numerical value or
2422  * operation), will produce an inexact result.
2423  *
2424  * Rational(10) / 3 #=> (10/3)
2425  * Rational(10) / 3.0 #=> 3.3333333333333335
2426  *
2427  * Rational(-8) ** Rational(1, 3)
2428  * #=> (1.0000000000000002+1.7320508075688772i)
2429  */
2430 void
2432 {
2433  VALUE compat;
2434 #undef rb_intern
2435 #define rb_intern(str) rb_intern_const(str)
2436 
2437  assert(fprintf(stderr, "assert() is now active\n"));
2438 
2439  id_abs = rb_intern("abs");
2440  id_cmp = rb_intern("<=>");
2441  id_convert = rb_intern("convert");
2442  id_eqeq_p = rb_intern("==");
2443  id_expt = rb_intern("**");
2444  id_fdiv = rb_intern("fdiv");
2445  id_floor = rb_intern("floor");
2446  id_idiv = rb_intern("div");
2447  id_inspect = rb_intern("inspect");
2448  id_integer_p = rb_intern("integer?");
2449  id_negate = rb_intern("-@");
2450  id_to_f = rb_intern("to_f");
2451  id_to_i = rb_intern("to_i");
2452  id_to_s = rb_intern("to_s");
2453  id_truncate = rb_intern("truncate");
2454  id_i_num = rb_intern("@numerator");
2455  id_i_den = rb_intern("@denominator");
2456 
2457  rb_cRational = rb_define_class("Rational", rb_cNumeric);
2458 
2460  rb_undef_method(CLASS_OF(rb_cRational), "allocate");
2461 
2462 #if 0
2463  rb_define_private_method(CLASS_OF(rb_cRational), "new!", nurat_s_new_bang, -1);
2465 #else
2467 #endif
2468 
2470 
2471  rb_define_method(rb_cRational, "numerator", nurat_numerator, 0);
2472  rb_define_method(rb_cRational, "denominator", nurat_denominator, 0);
2473 
2481 
2485 
2486 #if 0 /* NUBY */
2487  rb_define_method(rb_cRational, "//", nurat_idiv, 1);
2488 #endif
2489 
2490 #if 0
2491  rb_define_method(rb_cRational, "quot", nurat_quot, 1);
2492  rb_define_method(rb_cRational, "quotrem", nurat_quotrem, 1);
2493 #endif
2494 
2495 #if 0
2496  rb_define_method(rb_cRational, "rational?", nurat_true, 0);
2497  rb_define_method(rb_cRational, "exact?", nurat_true, 0);
2498 #endif
2499 
2504 
2508  rb_define_method(rb_cRational, "rationalize", nurat_rationalize, -1);
2509 
2511 
2514 
2516  compat = rb_define_class_under(rb_cRational, "compatible", rb_cObject);
2517  rb_define_private_method(compat, "marshal_load", nurat_marshal_load, 1);
2519 
2520  /* --- */
2521 
2522  rb_define_method(rb_cInteger, "gcd", rb_gcd, 1);
2523  rb_define_method(rb_cInteger, "lcm", rb_lcm, 1);
2524  rb_define_method(rb_cInteger, "gcdlcm", rb_gcdlcm, 1);
2525 
2527  rb_define_method(rb_cNumeric, "denominator", numeric_denominator, 0);
2528 
2530  rb_define_method(rb_cInteger, "denominator", integer_denominator, 0);
2531 
2532  rb_define_method(rb_cFloat, "numerator", float_numerator, 0);
2533  rb_define_method(rb_cFloat, "denominator", float_denominator, 0);
2534 
2536  rb_define_method(rb_cNilClass, "rationalize", nilclass_rationalize, -1);
2538  rb_define_method(rb_cInteger, "rationalize", integer_rationalize, -1);
2539  rb_define_method(rb_cFloat, "to_r", float_to_r, 0);
2540  rb_define_method(rb_cFloat, "rationalize", float_rationalize, -1);
2541 
2543 
2545 }
2546 
2547 /*
2548 Local variables:
2549 c-file-style: "ruby"
2550 End:
2551 */
static VALUE numeric_denominator(VALUE self)
Definition: rational.c:1785
#define RB_TYPE_P(obj, type)
#define ZERO
Definition: complex.c:15
RARRAY_PTR(q->result)[0]
#define f_ceil(x)
Definition: rational.c:1423
#define FLT_RADIX
Definition: numeric.c:35
static VALUE string_to_r_strict(VALUE self)
Definition: rational.c:2222
static VALUE f_sub(VALUE x, VALUE y)
Definition: rational.c:128
ssize_t n
Definition: bigdecimal.c:5655
static VALUE f_odd_p(VALUE integer)
Definition: rational.c:955
#define MUL_OVERFLOW_LONG_P(a, b)
static ID id_to_s
Definition: rational.c:26
static ID id_truncate
Definition: rational.c:26
static VALUE nurat_mul(VALUE self, VALUE other)
Definition: rational.c:850
static VALUE k_rational_p(VALUE x)
Definition: rational.c:268
void rb_match_busy(VALUE)
Definition: re.c:1189
RUBY_EXTERN VALUE rb_cNilClass
Definition: ripper.y:1447
#define f_truncate(x)
Definition: date_core.c:39
size_t strlen(const char *)
#define f_boolcast(x)
Definition: rational.c:30
static VALUE f_rational_new_no_reduce1(VALUE klass, VALUE x)
Definition: rational.c:552
static VALUE f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
Definition: rational.c:670
static int read_sign(const char **s)
Definition: rational.c:2046
const char * rb_obj_classname(VALUE)
Definition: variable.c:391
static VALUE nurat_expt(VALUE self, VALUE other)
Definition: rational.c:978
#define TWO
Definition: rational.c:22
Win32OLEIDispatch * p
Definition: win32ole.c:786
static VALUE nurat_floor(VALUE self)
Definition: rational.c:1199
static VALUE float_rationalize(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1986
int count
Definition: encoding.c:51
#define rb_check_trusted(obj)
static VALUE f_negative_p(VALUE x)
Definition: rational.c:174
#define get_dat1(x)
Definition: rational.c:359
static ID id_negate
Definition: rational.c:26
VALUE rb_rational_new(VALUE, VALUE)
Definition: rational.c:1741
static void nurat_int_check(VALUE num)
Definition: rational.c:450
static VALUE nurat_s_alloc(VALUE klass)
Definition: rational.c:380
static ID id_expt
Definition: rational.c:26
static VALUE nurat_coerce(VALUE self, VALUE other)
Definition: rational.c:1142
#define f_expt10(x)
Definition: rational.c:171
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
#define rb_usascii_str_new2
VALUE rb_gcd(VALUE self, VALUE other)
Definition: rational.c:1693
static VALUE nurat_s_new(int argc, VALUE *argv, VALUE klass)
Definition: rational.c:518
static VALUE nurat_loader(VALUE self, VALUE a)
Definition: rational.c:1631
#define rb_check_frozen(obj)
#define RFLOAT_VALUE(v)
static VALUE nurat_fdiv(VALUE self, VALUE other)
Definition: rational.c:947
#define NAN
Definition: missing.h:146
int ret
Definition: tcltklib.c:280
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1352
#define f_to_r(x)
Definition: rational.c:1764
Real * a
Definition: bigdecimal.c:1182
VALUE rb_eTypeError
Definition: error.c:511
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static ID id_to_i
Definition: rational.c:26
#define k_exact_zero_p(x)
Definition: rational.c:276
#define TYPE(x)
static ID id_integer_p
Definition: rational.c:26
static VALUE f_lt_p(VALUE x, VALUE y)
Definition: rational.c:94
#define RSTRING_PTR(str)
#define CLASS_OF(v)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
#define T_ARRAY
RUBY_EXTERN VALUE rb_cFloat
Definition: ripper.y:1439
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
static VALUE k_numeric_p(VALUE x)
Definition: rational.c:250
return Qtrue
Definition: tcltklib.c:9610
static VALUE float_denominator(VALUE self)
Definition: rational.c:1843
#define rb_rational_new1(x)
static VALUE f_one_p(VALUE x)
Definition: rational.c:204
#define rb_rational_raw2(x, y)
r
Definition: bigdecimal.c:1196
static VALUE integer_rationalize(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1900
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1522
void rb_must_asciicompat(VALUE)
Definition: string.c:1463
static VALUE nurat_floor_n(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1311
void Init_Rational(void)
Definition: rational.c:2431
#define T_FLOAT
VALUE rb_lcm(VALUE x, VALUE y)
Definition: rational.c:1711
static ID id_fdiv
Definition: rational.c:26
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1358
static VALUE nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den)
Definition: rational.c:472
#define LONG2NUM(x)
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1111
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2155
int truncate(const char *path, off_t new_size)
static VALUE f_rational_new_no_reduce2(VALUE klass, VALUE x, VALUE y)
Definition: rational.c:559
d
Definition: strlcat.c:58
void rb_copy_generic_ivar(VALUE, VALUE)
Definition: variable.c:1042
static VALUE nurat_marshal_load(VALUE self, VALUE a)
Definition: rational.c:1655
static VALUE numeric_numerator(VALUE self)
Definition: rational.c:1773
static VALUE nurat_truncate_n(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1359
#define T_COMPLEX
VALUE rb_rational_raw(VALUE, VALUE)
Definition: rational.c:1735
VALUE rb_cstr_to_rat(const char *, int)
Definition: rational.c:2304
static VALUE f_add(VALUE x, VALUE y)
Definition: rational.c:54
static long i_gcd(long x, long y)
Definition: rational.c:284
#define neg(x)
Definition: time.c:171
#define rb_raise_zerodiv()
Definition: rational.c:385
#define f_mod(x, y)
Definition: date_core.c:34
static VALUE nurat_ceil(VALUE self)
Definition: rational.c:1206
static VALUE f_to_i(VALUE x)
Definition: rational.c:142
static VALUE integer_numerator(VALUE self)
Definition: rational.c:1797
static ID id_i_den
Definition: rational.c:26
static VALUE k_integer_p(VALUE x)
Definition: rational.c:256
return Qfalse
Definition: tcltklib.c:6779
#define FIXNUM_P(f)
static VALUE f_round_common(int argc, VALUE *argv, VALUE self, VALUE(*func)(VALUE))
Definition: rational.c:1261
VALUE rb_dbl2big(double d)
Definition: bignum.c:1353
VALUE rb_Rational(VALUE, VALUE)
Definition: rational.c:1749
#define RARRAY_LEN(a)
void nurat_canonicalization(int)
#define Qnil
Definition: tcltklib.c:1896
#define StringValuePtr(v)
#define val
Definition: tcltklib.c:1949
static VALUE f_imul(long a, long b)
Definition: rational.c:639
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
Definition: bignum.c:777
static int read_den(const char **s, int strict, VALUE *num)
Definition: rational.c:2161
RUBY_EXTERN VALUE rb_cRational
Definition: ripper.y:1452
static ID id_idiv
Definition: rational.c:26
static void Tcl_Interp * ip
Definition: stubs.c:43
#define Check_Type(v, t)
unsigned long ID
Definition: ripper.y:105
static ID id_eqeq_p
Definition: rational.c:26
#define T_RATIONAL
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1975
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
static VALUE VALUE obj
Definition: tcltklib.c:3158
#define RSTRING_LEN(str)
#define FIX2INT(x)
#define INT2FIX(i)
static VALUE nurat_dumper(VALUE self)
Definition: rational.c:1624
#define FIX2LONG(x)
void rb_backref_set(VALUE)
Definition: vm.c:768
static int read_digits(const char **s, int strict, VALUE *num, int *count)
Definition: rational.c:2064
#define T_STRING
VALUE rb_gcdlcm(VALUE self, VALUE other)
Definition: rational.c:1728
static VALUE nurat_to_s(VALUE self)
Definition: rational.c:1595
static int parse_rat(const char *s, int strict, VALUE *num)
Definition: rational.c:2207
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass)
Definition: rational.c:2316
static ID id_abs
Definition: rational.c:26
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:273
double rb_str_to_dbl(VALUE, int)
Definition: object.c:2600
#define fun1(n)
Definition: rational.c:39
static VALUE nurat_int_value(VALUE num)
Definition: rational.c:463
#define RUBY_FUNC_EXPORTED
Definition: defines.h:184
static int isdecimal(int c)
Definition: rational.c:2058
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
Definition: numeric.c:276
static VALUE nurat_eqeq_p(VALUE self, VALUE other)
Definition: rational.c:1104
static VALUE nurat_sub(VALUE self, VALUE other)
Definition: rational.c:771
#define DBL2NUM(dbl)
#define ALLOCA_N(type, n)
#define f_denominator(x)
Definition: rational.c:1761
static int read_rat_nos(const char **s, int sign, int strict, VALUE *num)
Definition: rational.c:2170
VALUE rb_rational_reciprocal(VALUE x)
Definition: rational.c:1675
static VALUE nurat_cmp(VALUE self, VALUE other)
Definition: rational.c:1055
#define RRATIONAL(obj)
#define k_exact_p(x)
Definition: rational.c:273
VALUE * argv
Definition: tcltklib.c:1971
RUBY_EXTERN VALUE rb_cInteger
Definition: ripper.y:1441
#define f_inspect(x)
Definition: date_core.c:45
static VALUE f_kind_of_p(VALUE x, VALUE c)
Definition: rational.c:244
static void float_decode_internal(VALUE self, VALUE *rf, VALUE *rn)
Definition: rational.c:1907
#define f_to_s(x)
Definition: date_core.c:44
#define f_reciprocal(x)
Definition: rational.c:1428
static VALUE f_minus_one_p(VALUE x)
Definition: rational.c:224
static VALUE float_numerator(VALUE self)
Definition: rational.c:1825
static VALUE nilclass_to_r(VALUE self)
Definition: rational.c:1858
register char * s
Definition: os2.c:56
static void skip_ws(const char **s)
Definition: rational.c:2200
#define RCOMPLEX(obj)
VP_EXPORT void
Definition: bigdecimal.c:5083
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1566
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:545
#define get_dat2(x, y)
Definition: rational.c:363
static VALUE f_lcm(VALUE x, VALUE y)
Definition: rational.c:352
static VALUE nurat_truncate(VALUE self)
Definition: rational.c:1228
static VALUE string_to_r(VALUE self)
Definition: rational.c:2278
#define T_FIXNUM
VALUE rb_big_mul(VALUE x, VALUE y)
Definition: bignum.c:2660
static VALUE f_rational_new_bang1(VALUE klass, VALUE x)
Definition: rational.c:422
int argc
Definition: tcltklib.c:1970
static VALUE nurat_div(VALUE self, VALUE other)
Definition: rational.c:891
VALUE rb_Complex(VALUE x, VALUE y)
Definition: complex.c:1388
static VALUE nurat_round_n(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1384
RUBY_EXTERN int isinf(double)
Definition: isinf.c:56
static int read_rat(const char **s, int strict, VALUE *num)
Definition: rational.c:2188
#define isnan(x)
Definition: win32.h:313
static VALUE nurat_to_r(VALUE self)
Definition: rational.c:1417
RUBY_EXTERN VALUE rb_cString
Definition: ripper.y:1456
Real * b
Definition: bigdecimal.c:1182
#define DBL_MANT_DIG
Definition: acosh.c:19
VpDivd * c
Definition: bigdecimal.c:1205
#define f_lshift(x, n)
Definition: rational.c:1931
static VALUE f_gt_p(VALUE x, VALUE y)
Definition: rational.c:86
static VALUE f_rational_new1(VALUE klass, VALUE x)
Definition: rational.c:537
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Definition: marshal.c:113
#define T_BIGNUM
#define binop(n, op)
Definition: rational.c:32
static VALUE integer_denominator(VALUE self)
Definition: rational.c:1809
static VALUE f_cmp(VALUE x, VALUE y)
Definition: rational.c:64
static VALUE nurat_f_rational(int argc, VALUE *argv, VALUE klass)
Definition: rational.c:592
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1123
static VALUE f_to_f(VALUE x)
Definition: rational.c:149
static VALUE nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den)
Definition: rational.c:498
void rb_str_modify(VALUE)
Definition: string.c:1369
#define NEWOBJ_OF(obj, type, klass, flags)
static VALUE nurat_to_f(VALUE self)
Definition: rational.c:1401
static int islettere(int c)
Definition: rational.c:2106
#define f
#define NUM2LONG(x)
static VALUE f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
Definition: rational.c:799
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
static int read_num(const char **s, int numsign, int strict, VALUE *num)
Definition: rational.c:2112
static VALUE f_rational_new_bang2(VALUE klass, VALUE x, VALUE y)
Definition: rational.c:428
VALUE rb_hash(VALUE)
Definition: hash.c:66
int t
Definition: ripper.c:13760
#define f_expt(x, y)
Definition: date_core.c:36
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1422
static ID id_inspect
Definition: rational.c:26
static VALUE f_format(VALUE self, VALUE(*func)(VALUE))
Definition: rational.c:1572
static VALUE nurat_ceil_n(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1335
static ID id_cmp
Definition: rational.c:26
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
st_data_t st_index_t
Definition: ripper.y:63
#define LONG2FIX(i)
#define f_positive_p(x)
Definition: rational.c:181
static VALUE nilclass_rationalize(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1871
klass
Definition: tcltklib.c:3504
static VALUE f_div(VALUE x, VALUE y)
Definition: rational.c:78
#define INT2NUM(x)
static ID id_i_num
Definition: rational.c:26
static VALUE f_mul(VALUE x, VALUE y)
Definition: rational.c:104
static VALUE nurat_add(VALUE self, VALUE other)
Definition: rational.c:731
VALUE rb_backref_get(void)
Definition: vm.c:762
static VALUE nurat_round(VALUE self)
Definition: rational.c:1237
VALUE rb_int2big(SIGNED_VALUE n)
Definition: bignum.c:309
static VALUE nurat_denominator(VALUE self)
Definition: rational.c:628
static VALUE nurat_numerator(VALUE self)
Definition: rational.c:609
#define assert(condition)
Definition: ossl.h:45
static ID id_to_f
Definition: rational.c:26
static VALUE nurat_marshal_dump(VALUE self)
Definition: rational.c:1643
BDIGIT e
Definition: bigdecimal.c:5085
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:805
#define f_nonzero_p(x)
Definition: rational.c:201
unsigned long VALUE
Definition: ripper.y:104
static ID id_convert
Definition: rational.c:26
#define f_numerator(x)
Definition: rational.c:1758
ssize_t ix
Definition: bigdecimal.c:5655
static void nurat_rationalize_internal(VALUE a, VALUE b, VALUE *p, VALUE *q)
Definition: rational.c:1490
static VALUE integer_to_r(VALUE self)
Definition: rational.c:1887
#define ONE
Definition: rational.c:21
#define f_abs(x)
Definition: date_core.c:26
#define f_negate(x)
Definition: date_core.c:27
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
Definition: bignum.c:579
static VALUE nurat_hash(VALUE self)
Definition: rational.c:1557
#define rb_intern(str)
static VALUE f_zero_p(VALUE x)
Definition: rational.c:184
static VALUE nurat_rationalize(int argc, VALUE *argv, VALUE self)
Definition: rational.c:1533
BDIGIT v
Definition: bigdecimal.c:5656
#define mod(x, y)
Definition: date_strftime.c:28
static ID id_floor
Definition: rational.c:26
static VALUE float_to_r(VALUE self)
Definition: rational.c:1950
#define NULL
Definition: _sdbm.c:103
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
Definition: numeric.c:269
q
Definition: tcltklib.c:2968
RUBY_EXTERN VALUE rb_eFloatDomainError
Definition: ripper.y:1486
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1340
static int issign(int c)
Definition: rational.c:2040
void rb_warn(const char *fmt,...)
Definition: error.c:216
#define f_idiv(x, y)
Definition: date_core.c:33
#define fun2(n)
Definition: rational.c:46
static VALUE f_rational_new2(VALUE klass, VALUE x, VALUE y)
Definition: rational.c:544
static VALUE f_gcd(VALUE x, VALUE y)
Definition: rational.c:305
VALUE rb_eArgError
Definition: error.c:512
RUBY_EXTERN VALUE rb_cNumeric
Definition: ripper.y:1448
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2349
static VALUE k_float_p(VALUE x)
Definition: rational.c:262
static VALUE nurat_inspect(VALUE self)
Definition: rational.c:1611
#define rb_rational_new2(x, y)
static VALUE nurat_s_new_internal(VALUE klass, VALUE num, VALUE den)
Definition: rational.c:369
static VALUE f_eqeq_p(VALUE x, VALUE y)
Definition: rational.c:160
#define k_exact_one_p(x)
Definition: rational.c:277