[前][次][番号順一覧][スレッド一覧]

ruby-changes:4322

From: ko1@a...
Date: Thu, 20 Mar 2008 21:27:19 +0900 (JST)
Subject: [ruby-changes:4322] tadf - Ruby:r15812 (trunk): improvements.

tadf	2008-03-20 21:26:58 +0900 (Thu, 20 Mar 2008)

  New Revision: 15812

  Added files:
    trunk/test/ruby/test_rational2.rb
  Modified files:
    trunk/ChangeLog
    trunk/complex.c
    trunk/rational.c

  Log:
    improvements.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/complex.c?r1=15812&r2=15811&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15812&r2=15811&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/rational.c?r1=15812&r2=15811&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_rational2.rb?revision=15812&view=markup
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_rational2.rb?r1=15812&r2=15811&diff_format=u

Index: complex.c
===================================================================
--- complex.c	(revision 15811)
+++ complex.c	(revision 15812)
@@ -28,63 +28,266 @@
   id_numerator, id_polar, id_quo, id_scalar_p, id_sin, id_sqrt, id_to_f,
   id_to_i, id_to_r, id_to_s, id_truncate;
 
-#define f_add(x,y) rb_funcall(x, '+', 1, y)
-#define f_div(x,y) rb_funcall(x, '/', 1, y)
-#define f_gt_p(x,y) rb_funcall(x, '>', 1, y)
-#define f_lt_p(x,y) rb_funcall(x, '<', 1, y)
-#define f_mod(x,y) rb_funcall(x, '%', 1, y)
-#define f_mul(x,y) rb_funcall(x, '*', 1, y)
-#define f_sub(x,y) rb_funcall(x, '-', 1, y)
-#define f_xor(x,y) rb_funcall(x, '^', 1, y)
+#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
 
-#define f_abs(x) rb_funcall(x, id_abs, 0)
-#define f_abs2(x) rb_funcall(x, id_abs2, 0)
-#define f_arg(x) rb_funcall(x, id_arg, 0)
-#define f_conjugate(x) rb_funcall(x, id_conjugate, 0)
-#define f_denominator(x) rb_funcall(x, id_denominator, 0)
-#define f_exact_p(x) rb_funcall(x, id_exact_p, 0)
-#define f_floor(x) rb_funcall(x, id_floor, 0)
-#define f_negate(x) rb_funcall(x, id_negate, 0)
-#define f_numerator(x) rb_funcall(x, id_numerator, 0)
-#define f_polar(x) rb_funcall(x, id_polar, 0)
-#define f_scalar_p(x) rb_funcall(x, id_scalar_p, 0)
-#define f_to_f(x) rb_funcall(x, id_to_f, 0)
-#define f_to_i(x) rb_funcall(x, id_to_i, 0)
-#define f_to_r(x) rb_funcall(x, id_to_r, 0)
-#define f_to_s(x) rb_funcall(x, id_to_s, 0)
-#define f_truncate(x) rb_funcall(x, id_truncate, 0)
-#define f_cmp(x,y) rb_funcall(x, id_cmp, 1, y)
-#define f_coerce(x,y) rb_funcall(x, id_coerce, 1, y)
-#define f_divmod(x,y) rb_funcall(x, id_divmod, 1, y)
-#define f_equal_p(x,y) rb_funcall(x, id_equal_p, 1, y)
-#define f_expt(x,y) rb_funcall(x, id_expt, 1, y)
-#define f_idiv(x,y) rb_funcall(x, id_idiv, 1, y)
-#define f_inspect(x) rb_funcall(x, id_inspect, 0)
-#define f_quo(x,y) rb_funcall(x, id_quo, 1, y)
+#define binop(n,op) \
+inline static VALUE \
+f_##n(VALUE x, VALUE y)\
+{\
+  return rb_funcall(x, op, 1, y);\
+}
 
-#if 0
-#define m_cos(x) rb_funcall(rb_mMath, id_cos, 1, x)
-#define m_exp_bang(x) rb_funcall(rb_mMath, id_exp_bang, 1, x)
-#define m_log_bang(x) rb_funcall(rb_mMath, id_log_bang, 1, x)
-#define m_sin(x) rb_funcall(rb_mMath, id_sin, 1, x)
-#define m_sqrt(x) rb_funcall(rb_mMath, id_sqrt, 1, x)
-#define m_atan2_bang(x,y) rb_funcall(rb_mMath, id_atan2_bang, 2, x, y)
-#define m_hypot(x,y) rb_funcall(rb_mMath, id_hypot, 2, x, y)
-#endif
+#define fun1(n) \
+inline static VALUE \
+f_##n(VALUE x)\
+{\
+  return rb_funcall(x, id_##n, 0);\
+}
 
-#define f_negative_p(x) f_lt_p(x, ZERO)
-#define f_zero_p(x) f_equal_p(x, ZERO)
-#define f_one_p(x) f_equal_p(x, ONE)
-#define f_kind_of_p(x,c) rb_obj_is_kind_of(x, c)
-#define k_numeric_p(x) f_kind_of_p(x, rb_cNumeric)
-#define k_integer_p(x) f_kind_of_p(x, rb_cInteger)
-#define k_float_p(x) f_kind_of_p(x, rb_cFloat)
-#define k_rational_p(x) f_kind_of_p(x, rb_cRational)
-#define k_complex_p(x) f_kind_of_p(x, rb_cComplex)
+#define fun2(n) \
+inline static VALUE \
+f_##n(VALUE x, VALUE y)\
+{\
+  return rb_funcall(x, id_##n, 1, y);\
+}
 
-#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
+#define math1(n) \
+inline static VALUE \
+m_##n(VALUE x)\
+{\
+  return rb_funcall(rb_mMath, id_##n, 1, x);\
+}
 
+#define math2(n) \
+inline static VALUE \
+m_##n(VALUE x, VALUE y)\
+{\
+  return rb_funcall(rb_mMath, id_##n, 2, x, y);\
+}
+
 inline static VALUE
+f_add(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(y)) {
+     if (FIX2INT(y) == 0)
+       _r = x;
+     else
+       _r = rb_funcall(x, '+', 1, y);
+   } else if (FIXNUM_P(x)) {
+     if (FIX2INT(x) == 0)
+       _r = y;
+     else
+       _r = rb_funcall(x, '+', 1, y);
+   } else
+     _r = rb_funcall(x, '+', 1, y);
+   return _r;
+}
+
+inline static VALUE
+f_div(x, y)
+{
+  VALUE _r;
+  if (FIXNUM_P(y) && FIX2INT(y) == 1)
+    _r = x;
+   else
+     _r = rb_funcall(x, '/', 1, y);
+  return _r;
+}
+
+inline static VALUE
+f_gt_p(VALUE x, VALUE y)
+{
+   VALUE _r;
+  if (FIXNUM_P(x) && FIXNUM_P(y))
+    _r = f_boolcast(FIX2INT(x) > FIX2INT(y));
+  else
+    _r = rb_funcall(x, '>', 1, y);
+  return _r;
+}
+
+inline static VALUE
+f_lt_p(VALUE x, VALUE y)
+{
+   VALUE _r;
+  if (FIXNUM_P(x) && FIXNUM_P(y))
+    _r = f_boolcast(FIX2INT(x) < FIX2INT(y));
+  else
+    _r = rb_funcall(x, '<', 1, y);
+  return _r;
+}
+
+binop(mod, '%')
+
+inline static VALUE
+f_mul(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(y)) {
+     int _iy = FIX2INT(y);
+     if (_iy == 0) {
+       if (TYPE(x) == T_FLOAT)
+	 _r = rb_float_new(0.0);
+       else
+	 _r = ZERO;
+     } else if (_iy == 1)
+       _r = x;
+     else
+       _r = rb_funcall(x, '*', 1, y);
+   } else if (FIXNUM_P(x)) {
+     int _ix = FIX2INT(x);
+     if (_ix == 0) {
+       if (TYPE(y) == T_FLOAT)
+	 _r = rb_float_new(0.0);
+       else
+	 _r = ZERO;
+     } else if (_ix == 1)
+       _r = y;
+     else
+       _r = rb_funcall(x, '*', 1, y);
+   } else
+     _r = rb_funcall(x, '*', 1, y);
+   return _r;
+}
+
+inline static VALUE
+f_sub(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(y)) {
+     if (FIX2INT(y) == 0)
+       _r = x;
+     else
+       _r = rb_funcall(x, '-', 1, y);
+   } else
+    _r = rb_funcall(x, '-', 1, y);
+   return _r;
+}
+
+binop(xor, '^')
+
+fun1(abs)
+fun1(abs2)
+fun1(arg)
+fun1(conjugate)
+fun1(denominator)
+fun1(exact_p)
+fun1(floor)
+fun1(inspect)
+fun1(negate)
+fun1(numerator)
+fun1(polar)
+fun1(scalar_p)
+fun1(to_f)
+fun1(to_i)
+fun1(to_r)
+fun1(to_s)
+fun1(truncate)
+
+inline static VALUE
+f_cmp(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(x) && FIXNUM_P(y)) {
+     int c = FIX2INT(x) - FIX2INT(y);
+     if (c > 0)
+       c = 1;
+     else if (c < 0)
+       c = -1;
+     _r = INT2FIX(c);
+   } else
+     _r = rb_funcall(x, id_cmp, 1, y);
+   return _r;
+}
+
+fun2(coerce)
+fun2(divmod)
+
+inline static VALUE
+f_equal_p(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(x) && FIXNUM_P(y))
+     _r = f_boolcast(FIX2INT(x) == FIX2INT(y));
+   else
+     _r = rb_funcall(x, id_equal_p, 1, y);
+   return _r;
+}
+
+fun2(expt)
+fun2(idiv)
+fun2(quo)
+
+inline static VALUE
+f_negative_p(VALUE x)
+{
+   VALUE _r;
+  if (FIXNUM_P(x))
+    _r = f_boolcast(FIX2INT(x) < 0);
+  else
+    _r = rb_funcall(x, '<', 1, ZERO);
+  return _r;
+}
+
+inline static VALUE
+f_zero_p(VALUE x)
+{
+   VALUE _r;
+   if (FIXNUM_P(x))
+     _r = f_boolcast(FIX2INT(x) == 0);
+   else
+     _r = rb_funcall(x, id_equal_p, 1, ZERO);
+   return _r;
+}
+
+inline static VALUE
+f_one_p(VALUE x)
+{
+   VALUE _r;
+   if (FIXNUM_P(x))
+     _r = f_boolcast(FIX2INT(x) == 1);
+   else
+     _r = rb_funcall(x, id_equal_p, 1, ONE);
+   return _r;
+}
+
+inline static VALUE
+f_kind_of_p(VALUE x, VALUE c)
+{
+  return rb_obj_is_kind_of(x, c);
+}
+
+inline static VALUE
+k_numeric_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cNumeric);
+}
+
+inline static VALUE
+k_integer_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cInteger);
+}
+
+inline static VALUE
+k_float_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cFloat);
+}
+
+inline static VALUE
+k_rational_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cRational);
+}
+
+inline static VALUE
+k_complex_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cComplex);
+}
+
+inline static VALUE
 f_generic_p(VALUE x)
 {
   switch (TYPE(x)) {
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 15811)
+++ ChangeLog	(revision 15812)
@@ -1,3 +1,12 @@
+Thu Mar 20 21:20:19 2008  Tadayoshi Funaba  <tadf@d...>
+
+	* rational.c: some improvements (include Shin-ichiro HARA's
+	  effort).
+
+	* complex.c: some improvemtns.
+
+	* test/ruby/test_rational2.rb: new.
+
 Thu Mar 20 00:21:12 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* io.c (argf_initialize_copy): get rid of segfault.
Index: test/ruby/test_rational2.rb
===================================================================
--- test/ruby/test_rational2.rb	(revision 0)
+++ test/ruby/test_rational2.rb	(revision 15812)
@@ -0,0 +1,1360 @@
+require 'test/unit'
+
+class Rational_Test2 < Test::Unit::TestCase
+
+  def test_kumi
+    assert_equal(Rational(2, 1),
+                 Rational(1, 1) + Rational(1, 1))
+    assert_equal(Rational(0, 1),
+                 Rational(1, 1) - Rational(1, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(1, 1) * Rational(1, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(1, 1) / Rational(1, 1))
+    assert_equal(Rational(3, 1),
+                 Rational(1, 1) + Rational(2, 1))
+    assert_equal(Rational(-1, 1),
+                 Rational(1, 1) - Rational(2, 1))
+    assert_equal(Rational(2, 1),
+                 Rational(1, 1) * Rational(2, 1))
+    assert_equal(Rational(1, 2),
+                 Rational(1, 1) / Rational(2, 1))
+    assert_equal(Rational(4, 1),
+                 Rational(1, 1) + Rational(3, 1))
+    assert_equal(Rational(-2, 1),
+                 Rational(1, 1) - Rational(3, 1))
+    assert_equal(Rational(3, 1),
+                 Rational(1, 1) * Rational(3, 1))
+    assert_equal(Rational(1, 3),
+                 Rational(1, 1) / Rational(3, 1))
+    assert_equal(Rational(1073741790, 1),
+                 Rational(1, 1) + Rational(1073741789, 1))
+    assert_equal(Rational(-1073741788, 1),
+                 Rational(1, 1) - Rational(1073741789, 1))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(1, 1) * Rational(1073741789, 1))
+    assert_equal(Rational(1, 1073741789),
+                 Rational(1, 1) / Rational(1073741789, 1))
+    assert_equal(Rational(1073741828, 1),
+                 Rational(1, 1) + Rational(1073741827, 1))
+    assert_equal(Rational(-1073741826, 1),
+                 Rational(1, 1) - Rational(1073741827, 1))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(1, 1) * Rational(1073741827, 1))
+    assert_equal(Rational(1, 1073741827),
+                 Rational(1, 1) / Rational(1073741827, 1))
+    assert_equal(Rational(5, 3),
+                 Rational(1, 1) + Rational(2, 3))
+    assert_equal(Rational(1, 3),
+                 Rational(1, 1) - Rational(2, 3))
+    assert_equal(Rational(2, 3),
+                 Rational(1, 1) * Rational(2, 3))
+    assert_equal(Rational(3, 2),
+                 Rational(1, 1) / Rational(2, 3))
+    assert_equal(Rational(5, 2),
+                 Rational(1, 1) + Rational(3, 2))
+    assert_equal(Rational(-1, 2),
+                 Rational(1, 1) - Rational(3, 2))
+    assert_equal(Rational(3, 2),
+                 Rational(1, 1) * Rational(3, 2))
+    assert_equal(Rational(2, 3),
+                 Rational(1, 1) / Rational(3, 2))
+    assert_equal(Rational(1073741792, 1073741789),
+                 Rational(1, 1) + Rational(3, 1073741789))
+    assert_equal(Rational(1073741786, 1073741789),
+                 Rational(1, 1) - Rational(3, 1073741789))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(1, 1) * Rational(3, 1073741789))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1, 1) / Rational(3, 1073741789))
+    assert_equal(Rational(1073741792, 3),
+                 Rational(1, 1) + Rational(1073741789, 3))
+    assert_equal(Rational(-1073741786, 3),
+                 Rational(1, 1) - Rational(1073741789, 3))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1, 1) * Rational(1073741789, 3))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(1, 1) / Rational(1073741789, 3))
+    assert_equal(Rational(1073741830, 1073741827),
+                 Rational(1, 1) + Rational(3, 1073741827))
+    assert_equal(Rational(1073741824, 1073741827),
+                 Rational(1, 1) - Rational(3, 1073741827))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(1, 1) * Rational(3, 1073741827))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1, 1) / Rational(3, 1073741827))
+    assert_equal(Rational(1073741830, 3),
+                 Rational(1, 1) + Rational(1073741827, 3))
+    assert_equal(Rational(-1073741824, 3),
+                 Rational(1, 1) - Rational(1073741827, 3))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1, 1) * Rational(1073741827, 3))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(1, 1) / Rational(1073741827, 3))
+    assert_equal(Rational(2147483616, 1073741827),
+                 Rational(1, 1) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(38, 1073741827),
+                 Rational(1, 1) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(1, 1) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(1, 1) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(2147483616, 1073741789),
+                 Rational(1, 1) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(-38, 1073741789),
+                 Rational(1, 1) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(1, 1) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(1, 1) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(3, 1),
+                 Rational(2, 1) + Rational(1, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(2, 1) - Rational(1, 1))
+    assert_equal(Rational(2, 1),
+                 Rational(2, 1) * Rational(1, 1))
+    assert_equal(Rational(2, 1),
+                 Rational(2, 1) / Rational(1, 1))
+    assert_equal(Rational(4, 1),
+                 Rational(2, 1) + Rational(2, 1))
+    assert_equal(Rational(0, 1),
+                 Rational(2, 1) - Rational(2, 1))
+    assert_equal(Rational(4, 1),
+                 Rational(2, 1) * Rational(2, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(2, 1) / Rational(2, 1))
+    assert_equal(Rational(5, 1),
+                 Rational(2, 1) + Rational(3, 1))
+    assert_equal(Rational(-1, 1),
+                 Rational(2, 1) - Rational(3, 1))
+    assert_equal(Rational(6, 1),
+                 Rational(2, 1) * Rational(3, 1))
+    assert_equal(Rational(2, 3),
+                 Rational(2, 1) / Rational(3, 1))
+    assert_equal(Rational(1073741791, 1),
+                 Rational(2, 1) + Rational(1073741789, 1))
+    assert_equal(Rational(-1073741787, 1),
+                 Rational(2, 1) - Rational(1073741789, 1))
+    assert_equal(Rational(2147483578, 1),
+                 Rational(2, 1) * Rational(1073741789, 1))
+    assert_equal(Rational(2, 1073741789),
+                 Rational(2, 1) / Rational(1073741789, 1))
+    assert_equal(Rational(1073741829, 1),
+                 Rational(2, 1) + Rational(1073741827, 1))
+    assert_equal(Rational(-1073741825, 1),
+                 Rational(2, 1) - Rational(1073741827, 1))
+    assert_equal(Rational(2147483654, 1),
+                 Rational(2, 1) * Rational(1073741827, 1))
+    assert_equal(Rational(2, 1073741827),
+                 Rational(2, 1) / Rational(1073741827, 1))
+    assert_equal(Rational(8, 3),
+                 Rational(2, 1) + Rational(2, 3))
+    assert_equal(Rational(4, 3),
+                 Rational(2, 1) - Rational(2, 3))
+    assert_equal(Rational(4, 3),
+                 Rational(2, 1) * Rational(2, 3))
+    assert_equal(Rational(3, 1),
+                 Rational(2, 1) / Rational(2, 3))
+    assert_equal(Rational(7, 2),
+                 Rational(2, 1) + Rational(3, 2))
+    assert_equal(Rational(1, 2),
+                 Rational(2, 1) - Rational(3, 2))
+    assert_equal(Rational(3, 1),
+                 Rational(2, 1) * Rational(3, 2))
+    assert_equal(Rational(4, 3),
+                 Rational(2, 1) / Rational(3, 2))
+    assert_equal(Rational(2147483581, 1073741789),
+                 Rational(2, 1) + Rational(3, 1073741789))
+    assert_equal(Rational(2147483575, 1073741789),
+                 Rational(2, 1) - Rational(3, 1073741789))
+    assert_equal(Rational(6, 1073741789),
+                 Rational(2, 1) * Rational(3, 1073741789))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(2, 1) / Rational(3, 1073741789))
+    assert_equal(Rational(1073741795, 3),
+                 Rational(2, 1) + Rational(1073741789, 3))
+    assert_equal(Rational(-1073741783, 3),
+                 Rational(2, 1) - Rational(1073741789, 3))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(2, 1) * Rational(1073741789, 3))
+    assert_equal(Rational(6, 1073741789),
+                 Rational(2, 1) / Rational(1073741789, 3))
+    assert_equal(Rational(2147483657, 1073741827),
+                 Rational(2, 1) + Rational(3, 1073741827))
+    assert_equal(Rational(2147483651, 1073741827),
+                 Rational(2, 1) - Rational(3, 1073741827))
+    assert_equal(Rational(6, 1073741827),
+                 Rational(2, 1) * Rational(3, 1073741827))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(2, 1) / Rational(3, 1073741827))
+    assert_equal(Rational(1073741833, 3),
+                 Rational(2, 1) + Rational(1073741827, 3))
+    assert_equal(Rational(-1073741821, 3),
+                 Rational(2, 1) - Rational(1073741827, 3))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(2, 1) * Rational(1073741827, 3))
+    assert_equal(Rational(6, 1073741827),
+                 Rational(2, 1) / Rational(1073741827, 3))
+    assert_equal(Rational(3221225443, 1073741827),
+                 Rational(2, 1) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741865, 1073741827),
+                 Rational(2, 1) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(2147483578, 1073741827),
+                 Rational(2, 1) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(2147483654, 1073741789),
+                 Rational(2, 1) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(3221225405, 1073741789),
+                 Rational(2, 1) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741751, 1073741789),
+                 Rational(2, 1) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(2147483654, 1073741789),
+                 Rational(2, 1) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(2147483578, 1073741827),
+                 Rational(2, 1) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(4, 1),
+                 Rational(3, 1) + Rational(1, 1))
+    assert_equal(Rational(2, 1),
+                 Rational(3, 1) - Rational(1, 1))
+    assert_equal(Rational(3, 1),
+                 Rational(3, 1) * Rational(1, 1))
+    assert_equal(Rational(3, 1),
+                 Rational(3, 1) / Rational(1, 1))
+    assert_equal(Rational(5, 1),
+                 Rational(3, 1) + Rational(2, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 1) - Rational(2, 1))
+    assert_equal(Rational(6, 1),
+                 Rational(3, 1) * Rational(2, 1))
+    assert_equal(Rational(3, 2),
+                 Rational(3, 1) / Rational(2, 1))
+    assert_equal(Rational(6, 1),
+                 Rational(3, 1) + Rational(3, 1))
+    assert_equal(Rational(0, 1),
+                 Rational(3, 1) - Rational(3, 1))
+    assert_equal(Rational(9, 1),
+                 Rational(3, 1) * Rational(3, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 1) / Rational(3, 1))
+    assert_equal(Rational(1073741792, 1),
+                 Rational(3, 1) + Rational(1073741789, 1))
+    assert_equal(Rational(-1073741786, 1),
+                 Rational(3, 1) - Rational(1073741789, 1))
+    assert_equal(Rational(3221225367, 1),
+                 Rational(3, 1) * Rational(1073741789, 1))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(3, 1) / Rational(1073741789, 1))
+    assert_equal(Rational(1073741830, 1),
+                 Rational(3, 1) + Rational(1073741827, 1))
+    assert_equal(Rational(-1073741824, 1),
+                 Rational(3, 1) - Rational(1073741827, 1))
+    assert_equal(Rational(3221225481, 1),
+                 Rational(3, 1) * Rational(1073741827, 1))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(3, 1) / Rational(1073741827, 1))
+    assert_equal(Rational(11, 3),
+                 Rational(3, 1) + Rational(2, 3))
+    assert_equal(Rational(7, 3),
+                 Rational(3, 1) - Rational(2, 3))
+    assert_equal(Rational(2, 1),
+                 Rational(3, 1) * Rational(2, 3))
+    assert_equal(Rational(9, 2),
+                 Rational(3, 1) / Rational(2, 3))
+    assert_equal(Rational(9, 2),
+                 Rational(3, 1) + Rational(3, 2))
+    assert_equal(Rational(3, 2),
+                 Rational(3, 1) - Rational(3, 2))
+    assert_equal(Rational(9, 2),
+                 Rational(3, 1) * Rational(3, 2))
+    assert_equal(Rational(2, 1),
+                 Rational(3, 1) / Rational(3, 2))
+    assert_equal(Rational(3221225370, 1073741789),
+                 Rational(3, 1) + Rational(3, 1073741789))
+    assert_equal(Rational(3221225364, 1073741789),
+                 Rational(3, 1) - Rational(3, 1073741789))
+    assert_equal(Rational(9, 1073741789),
+                 Rational(3, 1) * Rational(3, 1073741789))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(3, 1) / Rational(3, 1073741789))
+    assert_equal(Rational(1073741798, 3),
+                 Rational(3, 1) + Rational(1073741789, 3))
+    assert_equal(Rational(-1073741780, 3),
+                 Rational(3, 1) - Rational(1073741789, 3))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(3, 1) * Rational(1073741789, 3))
+    assert_equal(Rational(9, 1073741789),
+                 Rational(3, 1) / Rational(1073741789, 3))
+    assert_equal(Rational(3221225484, 1073741827),
+                 Rational(3, 1) + Rational(3, 1073741827))
+    assert_equal(Rational(3221225478, 1073741827),
+                 Rational(3, 1) - Rational(3, 1073741827))
+    assert_equal(Rational(9, 1073741827),
+                 Rational(3, 1) * Rational(3, 1073741827))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(3, 1) / Rational(3, 1073741827))
+    assert_equal(Rational(1073741836, 3),
+                 Rational(3, 1) + Rational(1073741827, 3))
+    assert_equal(Rational(-1073741818, 3),
+                 Rational(3, 1) - Rational(1073741827, 3))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(3, 1) * Rational(1073741827, 3))
+    assert_equal(Rational(9, 1073741827),
+                 Rational(3, 1) / Rational(1073741827, 3))
+    assert_equal(Rational(4294967270, 1073741827),
+                 Rational(3, 1) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(2147483692, 1073741827),
+                 Rational(3, 1) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(3221225367, 1073741827),
+                 Rational(3, 1) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(3221225481, 1073741789),
+                 Rational(3, 1) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(4294967194, 1073741789),
+                 Rational(3, 1) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(2147483540, 1073741789),
+                 Rational(3, 1) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(3221225481, 1073741789),
+                 Rational(3, 1) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(3221225367, 1073741827),
+                 Rational(3, 1) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741790, 1),
+                 Rational(1073741789, 1) + Rational(1, 1))
+    assert_equal(Rational(1073741788, 1),
+                 Rational(1073741789, 1) - Rational(1, 1))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(1073741789, 1) * Rational(1, 1))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(1073741789, 1) / Rational(1, 1))
+    assert_equal(Rational(1073741791, 1),
+                 Rational(1073741789, 1) + Rational(2, 1))
+    assert_equal(Rational(1073741787, 1),
+                 Rational(1073741789, 1) - Rational(2, 1))
+    assert_equal(Rational(2147483578, 1),
+                 Rational(1073741789, 1) * Rational(2, 1))
+    assert_equal(Rational(1073741789, 2),
+                 Rational(1073741789, 1) / Rational(2, 1))
+    assert_equal(Rational(1073741792, 1),
+                 Rational(1073741789, 1) + Rational(3, 1))
+    assert_equal(Rational(1073741786, 1),
+                 Rational(1073741789, 1) - Rational(3, 1))
+    assert_equal(Rational(3221225367, 1),
+                 Rational(1073741789, 1) * Rational(3, 1))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1073741789, 1) / Rational(3, 1))
+    assert_equal(Rational(2147483578, 1),
+                 Rational(1073741789, 1) + Rational(1073741789, 1))
+    assert_equal(Rational(0, 1),
+                 Rational(1073741789, 1) - Rational(1073741789, 1))
+    assert_equal(Rational(1152921429444920521, 1),
+                 Rational(1073741789, 1) * Rational(1073741789, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741789, 1) / Rational(1073741789, 1))
+    assert_equal(Rational(2147483616, 1),
+                 Rational(1073741789, 1) + Rational(1073741827, 1))
+    assert_equal(Rational(-38, 1),
+                 Rational(1073741789, 1) - Rational(1073741827, 1))
+    assert_equal(Rational(1152921470247108503, 1),
+                 Rational(1073741789, 1) * Rational(1073741827, 1))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(1073741789, 1) / Rational(1073741827, 1))
+    assert_equal(Rational(3221225369, 3),
+                 Rational(1073741789, 1) + Rational(2, 3))
+    assert_equal(Rational(3221225365, 3),
+                 Rational(1073741789, 1) - Rational(2, 3))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(1073741789, 1) * Rational(2, 3))
+    assert_equal(Rational(3221225367, 2),
+                 Rational(1073741789, 1) / Rational(2, 3))
+    assert_equal(Rational(2147483581, 2),
+                 Rational(1073741789, 1) + Rational(3, 2))
+    assert_equal(Rational(2147483575, 2),
+                 Rational(1073741789, 1) - Rational(3, 2))
+    assert_equal(Rational(3221225367, 2),
+                 Rational(1073741789, 1) * Rational(3, 2))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(1073741789, 1) / Rational(3, 2))
+    assert_equal(Rational(1152921429444920524, 1073741789),
+                 Rational(1073741789, 1) + Rational(3, 1073741789))
+    assert_equal(Rational(1152921429444920518, 1073741789),
+                 Rational(1073741789, 1) - Rational(3, 1073741789))
+    assert_equal(Rational(3, 1),
+                 Rational(1073741789, 1) * Rational(3, 1073741789))
+    assert_equal(Rational(1152921429444920521, 3),
+                 Rational(1073741789, 1) / Rational(3, 1073741789))
+    assert_equal(Rational(4294967156, 3),
+                 Rational(1073741789, 1) + Rational(1073741789, 3))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(1073741789, 1) - Rational(1073741789, 3))
+    assert_equal(Rational(1152921429444920521, 3),
+                 Rational(1073741789, 1) * Rational(1073741789, 3))
+    assert_equal(Rational(3, 1),
+                 Rational(1073741789, 1) / Rational(1073741789, 3))
+    assert_equal(Rational(1152921470247108506, 1073741827),
+                 Rational(1073741789, 1) + Rational(3, 1073741827))
+    assert_equal(Rational(1152921470247108500, 1073741827),
+                 Rational(1073741789, 1) - Rational(3, 1073741827))
+    assert_equal(Rational(3221225367, 1073741827),
+                 Rational(1073741789, 1) * Rational(3, 1073741827))
+    assert_equal(Rational(1152921470247108503, 3),
+                 Rational(1073741789, 1) / Rational(3, 1073741827))
+    assert_equal(Rational(4294967194, 3),
+                 Rational(1073741789, 1) + Rational(1073741827, 3))
+    assert_equal(Rational(2147483540, 3),
+                 Rational(1073741789, 1) - Rational(1073741827, 3))
+    assert_equal(Rational(1152921470247108503, 3),
+                 Rational(1073741789, 1) * Rational(1073741827, 3))
+    assert_equal(Rational(3221225367, 1073741827),
+                 Rational(1073741789, 1) / Rational(1073741827, 3))
+    assert_equal(Rational(1152921471320850292, 1073741827),
+                 Rational(1073741789, 1) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921469173366714, 1073741827),
+                 Rational(1073741789, 1) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921429444920521, 1073741827),
+                 Rational(1073741789, 1) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(1073741789, 1) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921430518662348, 1073741789),
+                 Rational(1073741789, 1) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921428371178694, 1073741789),
+                 Rational(1073741789, 1) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(1073741789, 1) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921429444920521, 1073741827),
+                 Rational(1073741789, 1) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741828, 1),
+                 Rational(1073741827, 1) + Rational(1, 1))
+    assert_equal(Rational(1073741826, 1),
+                 Rational(1073741827, 1) - Rational(1, 1))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(1073741827, 1) * Rational(1, 1))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(1073741827, 1) / Rational(1, 1))
+    assert_equal(Rational(1073741829, 1),
+                 Rational(1073741827, 1) + Rational(2, 1))
+    assert_equal(Rational(1073741825, 1),
+                 Rational(1073741827, 1) - Rational(2, 1))
+    assert_equal(Rational(2147483654, 1),
+                 Rational(1073741827, 1) * Rational(2, 1))
+    assert_equal(Rational(1073741827, 2),
+                 Rational(1073741827, 1) / Rational(2, 1))
+    assert_equal(Rational(1073741830, 1),
+                 Rational(1073741827, 1) + Rational(3, 1))
+    assert_equal(Rational(1073741824, 1),
+                 Rational(1073741827, 1) - Rational(3, 1))
+    assert_equal(Rational(3221225481, 1),
+                 Rational(1073741827, 1) * Rational(3, 1))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1073741827, 1) / Rational(3, 1))
+    assert_equal(Rational(2147483616, 1),
+                 Rational(1073741827, 1) + Rational(1073741789, 1))
+    assert_equal(Rational(38, 1),
+                 Rational(1073741827, 1) - Rational(1073741789, 1))
+    assert_equal(Rational(1152921470247108503, 1),
+                 Rational(1073741827, 1) * Rational(1073741789, 1))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(1073741827, 1) / Rational(1073741789, 1))
+    assert_equal(Rational(2147483654, 1),
+                 Rational(1073741827, 1) + Rational(1073741827, 1))
+    assert_equal(Rational(0, 1),
+                 Rational(1073741827, 1) - Rational(1073741827, 1))
+    assert_equal(Rational(1152921511049297929, 1),
+                 Rational(1073741827, 1) * Rational(1073741827, 1))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741827, 1) / Rational(1073741827, 1))
+    assert_equal(Rational(3221225483, 3),
+                 Rational(1073741827, 1) + Rational(2, 3))
+    assert_equal(Rational(3221225479, 3),
+                 Rational(1073741827, 1) - Rational(2, 3))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(1073741827, 1) * Rational(2, 3))
+    assert_equal(Rational(3221225481, 2),
+                 Rational(1073741827, 1) / Rational(2, 3))
+    assert_equal(Rational(2147483657, 2),
+                 Rational(1073741827, 1) + Rational(3, 2))
+    assert_equal(Rational(2147483651, 2),
+                 Rational(1073741827, 1) - Rational(3, 2))
+    assert_equal(Rational(3221225481, 2),
+                 Rational(1073741827, 1) * Rational(3, 2))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(1073741827, 1) / Rational(3, 2))
+    assert_equal(Rational(1152921470247108506, 1073741789),
+                 Rational(1073741827, 1) + Rational(3, 1073741789))
+    assert_equal(Rational(1152921470247108500, 1073741789),
+                 Rational(1073741827, 1) - Rational(3, 1073741789))
+    assert_equal(Rational(3221225481, 1073741789),
+                 Rational(1073741827, 1) * Rational(3, 1073741789))
+    assert_equal(Rational(1152921470247108503, 3),
+                 Rational(1073741827, 1) / Rational(3, 1073741789))
+    assert_equal(Rational(4294967270, 3),
+                 Rational(1073741827, 1) + Rational(1073741789, 3))
+    assert_equal(Rational(2147483692, 3),
+                 Rational(1073741827, 1) - Rational(1073741789, 3))
+    assert_equal(Rational(1152921470247108503, 3),
+                 Rational(1073741827, 1) * Rational(1073741789, 3))
+    assert_equal(Rational(3221225481, 1073741789),
+                 Rational(1073741827, 1) / Rational(1073741789, 3))
+    assert_equal(Rational(1152921511049297932, 1073741827),
+                 Rational(1073741827, 1) + Rational(3, 1073741827))
+    assert_equal(Rational(1152921511049297926, 1073741827),
+                 Rational(1073741827, 1) - Rational(3, 1073741827))
+    assert_equal(Rational(3, 1),
+                 Rational(1073741827, 1) * Rational(3, 1073741827))
+    assert_equal(Rational(1152921511049297929, 3),
+                 Rational(1073741827, 1) / Rational(3, 1073741827))
+    assert_equal(Rational(4294967308, 3),
+                 Rational(1073741827, 1) + Rational(1073741827, 3))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(1073741827, 1) - Rational(1073741827, 3))
+    assert_equal(Rational(1152921511049297929, 3),
+                 Rational(1073741827, 1) * Rational(1073741827, 3))
+    assert_equal(Rational(3, 1),
+                 Rational(1073741827, 1) / Rational(1073741827, 3))
+    assert_equal(Rational(1152921512123039718, 1073741827),
+                 Rational(1073741827, 1) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921509975556140, 1073741827),
+                 Rational(1073741827, 1) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(1073741827, 1) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921511049297929, 1073741789),
+                 Rational(1073741827, 1) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921471320850330, 1073741789),
+                 Rational(1073741827, 1) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921469173366676, 1073741789),
+                 Rational(1073741827, 1) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921511049297929, 1073741789),
+                 Rational(1073741827, 1) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(1073741827, 1) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(5, 3),
+                 Rational(2, 3) + Rational(1, 1))
+    assert_equal(Rational(-1, 3),
+                 Rational(2, 3) - Rational(1, 1))
+    assert_equal(Rational(2, 3),
+                 Rational(2, 3) * Rational(1, 1))
+    assert_equal(Rational(2, 3),
+                 Rational(2, 3) / Rational(1, 1))
+    assert_equal(Rational(8, 3),
+                 Rational(2, 3) + Rational(2, 1))
+    assert_equal(Rational(-4, 3),
+                 Rational(2, 3) - Rational(2, 1))
+    assert_equal(Rational(4, 3),
+                 Rational(2, 3) * Rational(2, 1))
+    assert_equal(Rational(1, 3),
+                 Rational(2, 3) / Rational(2, 1))
+    assert_equal(Rational(11, 3),
+                 Rational(2, 3) + Rational(3, 1))
+    assert_equal(Rational(-7, 3),
+                 Rational(2, 3) - Rational(3, 1))
+    assert_equal(Rational(2, 1),
+                 Rational(2, 3) * Rational(3, 1))
+    assert_equal(Rational(2, 9),
+                 Rational(2, 3) / Rational(3, 1))
+    assert_equal(Rational(3221225369, 3),
+                 Rational(2, 3) + Rational(1073741789, 1))
+    assert_equal(Rational(-3221225365, 3),
+                 Rational(2, 3) - Rational(1073741789, 1))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(2, 3) * Rational(1073741789, 1))
+    assert_equal(Rational(2, 3221225367),
+                 Rational(2, 3) / Rational(1073741789, 1))
+    assert_equal(Rational(3221225483, 3),
+                 Rational(2, 3) + Rational(1073741827, 1))
+    assert_equal(Rational(-3221225479, 3),
+                 Rational(2, 3) - Rational(1073741827, 1))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(2, 3) * Rational(1073741827, 1))
+    assert_equal(Rational(2, 3221225481),
+                 Rational(2, 3) / Rational(1073741827, 1))
+    assert_equal(Rational(4, 3),
+                 Rational(2, 3) + Rational(2, 3))
+    assert_equal(Rational(0, 1),
+                 Rational(2, 3) - Rational(2, 3))
+    assert_equal(Rational(4, 9),
+                 Rational(2, 3) * Rational(2, 3))
+    assert_equal(Rational(1, 1),
+                 Rational(2, 3) / Rational(2, 3))
+    assert_equal(Rational(13, 6),
+                 Rational(2, 3) + Rational(3, 2))
+    assert_equal(Rational(-5, 6),
+                 Rational(2, 3) - Rational(3, 2))
+    assert_equal(Rational(1, 1),
+                 Rational(2, 3) * Rational(3, 2))
+    assert_equal(Rational(4, 9),
+                 Rational(2, 3) / Rational(3, 2))
+    assert_equal(Rational(2147483587, 3221225367),
+                 Rational(2, 3) + Rational(3, 1073741789))
+    assert_equal(Rational(2147483569, 3221225367),
+                 Rational(2, 3) - Rational(3, 1073741789))
+    assert_equal(Rational(2, 1073741789),
+                 Rational(2, 3) * Rational(3, 1073741789))
+    assert_equal(Rational(2147483578, 9),
+                 Rational(2, 3) / Rational(3, 1073741789))
+    assert_equal(Rational(1073741791, 3),
+                 Rational(2, 3) + Rational(1073741789, 3))
+    assert_equal(Rational(-357913929, 1),
+                 Rational(2, 3) - Rational(1073741789, 3))
+    assert_equal(Rational(2147483578, 9),
+                 Rational(2, 3) * Rational(1073741789, 3))
+    assert_equal(Rational(2, 1073741789),
+                 Rational(2, 3) / Rational(1073741789, 3))
+    assert_equal(Rational(2147483663, 3221225481),
+                 Rational(2, 3) + Rational(3, 1073741827))
+    assert_equal(Rational(2147483645, 3221225481),
+                 Rational(2, 3) - Rational(3, 1073741827))
+    assert_equal(Rational(2, 1073741827),
+                 Rational(2, 3) * Rational(3, 1073741827))
+    assert_equal(Rational(2147483654, 9),
+                 Rational(2, 3) / Rational(3, 1073741827))
+    assert_equal(Rational(357913943, 1),
+                 Rational(2, 3) + Rational(1073741827, 3))
+    assert_equal(Rational(-1073741825, 3),
+                 Rational(2, 3) - Rational(1073741827, 3))
+    assert_equal(Rational(2147483654, 9),
+                 Rational(2, 3) * Rational(1073741827, 3))
+    assert_equal(Rational(2, 1073741827),
+                 Rational(2, 3) / Rational(1073741827, 3))
+    assert_equal(Rational(5368709021, 3221225481),
+                 Rational(2, 3) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(-1073741713, 3221225481),
+                 Rational(2, 3) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(2147483578, 3221225481),
+                 Rational(2, 3) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(2147483654, 3221225367),
+                 Rational(2, 3) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(5368709059, 3221225367),
+                 Rational(2, 3) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(-1073741903, 3221225367),
+                 Rational(2, 3) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(2147483654, 3221225367),
+                 Rational(2, 3) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(2147483578, 3221225481),
+                 Rational(2, 3) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(5, 2),
+                 Rational(3, 2) + Rational(1, 1))
+    assert_equal(Rational(1, 2),
+                 Rational(3, 2) - Rational(1, 1))
+    assert_equal(Rational(3, 2),
+                 Rational(3, 2) * Rational(1, 1))
+    assert_equal(Rational(3, 2),
+                 Rational(3, 2) / Rational(1, 1))
+    assert_equal(Rational(7, 2),
+                 Rational(3, 2) + Rational(2, 1))
+    assert_equal(Rational(-1, 2),
+                 Rational(3, 2) - Rational(2, 1))
+    assert_equal(Rational(3, 1),
+                 Rational(3, 2) * Rational(2, 1))
+    assert_equal(Rational(3, 4),
+                 Rational(3, 2) / Rational(2, 1))
+    assert_equal(Rational(9, 2),
+                 Rational(3, 2) + Rational(3, 1))
+    assert_equal(Rational(-3, 2),
+                 Rational(3, 2) - Rational(3, 1))
+    assert_equal(Rational(9, 2),
+                 Rational(3, 2) * Rational(3, 1))
+    assert_equal(Rational(1, 2),
+                 Rational(3, 2) / Rational(3, 1))
+    assert_equal(Rational(2147483581, 2),
+                 Rational(3, 2) + Rational(1073741789, 1))
+    assert_equal(Rational(-2147483575, 2),
+                 Rational(3, 2) - Rational(1073741789, 1))
+    assert_equal(Rational(3221225367, 2),
+                 Rational(3, 2) * Rational(1073741789, 1))
+    assert_equal(Rational(3, 2147483578),
+                 Rational(3, 2) / Rational(1073741789, 1))
+    assert_equal(Rational(2147483657, 2),
+                 Rational(3, 2) + Rational(1073741827, 1))
+    assert_equal(Rational(-2147483651, 2),
+                 Rational(3, 2) - Rational(1073741827, 1))
+    assert_equal(Rational(3221225481, 2),
+                 Rational(3, 2) * Rational(1073741827, 1))
+    assert_equal(Rational(3, 2147483654),
+                 Rational(3, 2) / Rational(1073741827, 1))
+    assert_equal(Rational(13, 6),
+                 Rational(3, 2) + Rational(2, 3))
+    assert_equal(Rational(5, 6),
+                 Rational(3, 2) - Rational(2, 3))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 2) * Rational(2, 3))
+    assert_equal(Rational(9, 4),
+                 Rational(3, 2) / Rational(2, 3))
+    assert_equal(Rational(3, 1),
+                 Rational(3, 2) + Rational(3, 2))
+    assert_equal(Rational(0, 1),
+                 Rational(3, 2) - Rational(3, 2))
+    assert_equal(Rational(9, 4),
+                 Rational(3, 2) * Rational(3, 2))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 2) / Rational(3, 2))
+    assert_equal(Rational(3221225373, 2147483578),
+                 Rational(3, 2) + Rational(3, 1073741789))
+    assert_equal(Rational(3221225361, 2147483578),
+                 Rational(3, 2) - Rational(3, 1073741789))
+    assert_equal(Rational(9, 2147483578),
+                 Rational(3, 2) * Rational(3, 1073741789))
+    assert_equal(Rational(1073741789, 2),
+                 Rational(3, 2) / Rational(3, 1073741789))
+    assert_equal(Rational(2147483587, 6),
+                 Rational(3, 2) + Rational(1073741789, 3))
+    assert_equal(Rational(-2147483569, 6),
+                 Rational(3, 2) - Rational(1073741789, 3))
+    assert_equal(Rational(1073741789, 2),
+                 Rational(3, 2) * Rational(1073741789, 3))
+    assert_equal(Rational(9, 2147483578),
+                 Rational(3, 2) / Rational(1073741789, 3))
+    assert_equal(Rational(3221225487, 2147483654),
+                 Rational(3, 2) + Rational(3, 1073741827))
+    assert_equal(Rational(3221225475, 2147483654),
+                 Rational(3, 2) - Rational(3, 1073741827))
+    assert_equal(Rational(9, 2147483654),
+                 Rational(3, 2) * Rational(3, 1073741827))
+    assert_equal(Rational(1073741827, 2),
+                 Rational(3, 2) / Rational(3, 1073741827))
+    assert_equal(Rational(2147483663, 6),
+                 Rational(3, 2) + Rational(1073741827, 3))
+    assert_equal(Rational(-2147483645, 6),
+                 Rational(3, 2) - Rational(1073741827, 3))
+    assert_equal(Rational(1073741827, 2),
+                 Rational(3, 2) * Rational(1073741827, 3))
+    assert_equal(Rational(9, 2147483654),
+                 Rational(3, 2) / Rational(1073741827, 3))
+    assert_equal(Rational(5368709059, 2147483654),
+                 Rational(3, 2) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741903, 2147483654),
+                 Rational(3, 2) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(3221225367, 2147483654),
+                 Rational(3, 2) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(3221225481, 2147483578),
+                 Rational(3, 2) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(5368709021, 2147483578),
+                 Rational(3, 2) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741713, 2147483578),
+                 Rational(3, 2) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(3221225481, 2147483578),
+                 Rational(3, 2) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(3221225367, 2147483654),
+                 Rational(3, 2) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741792, 1073741789),
+                 Rational(3, 1073741789) + Rational(1, 1))
+    assert_equal(Rational(-1073741786, 1073741789),
+                 Rational(3, 1073741789) - Rational(1, 1))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(3, 1073741789) * Rational(1, 1))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(3, 1073741789) / Rational(1, 1))
+    assert_equal(Rational(2147483581, 1073741789),
+                 Rational(3, 1073741789) + Rational(2, 1))
+    assert_equal(Rational(-2147483575, 1073741789),
+                 Rational(3, 1073741789) - Rational(2, 1))
+    assert_equal(Rational(6, 1073741789),
+                 Rational(3, 1073741789) * Rational(2, 1))
+    assert_equal(Rational(3, 2147483578),
+                 Rational(3, 1073741789) / Rational(2, 1))
+    assert_equal(Rational(3221225370, 1073741789),
+                 Rational(3, 1073741789) + Rational(3, 1))
+    assert_equal(Rational(-3221225364, 1073741789),
+                 Rational(3, 1073741789) - Rational(3, 1))
+    assert_equal(Rational(9, 1073741789),
+                 Rational(3, 1073741789) * Rational(3, 1))
+    assert_equal(Rational(1, 1073741789),
+                 Rational(3, 1073741789) / Rational(3, 1))
+    assert_equal(Rational(1152921429444920524, 1073741789),
+                 Rational(3, 1073741789) + Rational(1073741789, 1))
+    assert_equal(Rational(-1152921429444920518, 1073741789),
+                 Rational(3, 1073741789) - Rational(1073741789, 1))
+    assert_equal(Rational(3, 1),
+                 Rational(3, 1073741789) * Rational(1073741789, 1))
+    assert_equal(Rational(3, 1152921429444920521),
+                 Rational(3, 1073741789) / Rational(1073741789, 1))
+    assert_equal(Rational(1152921470247108506, 1073741789),
+                 Rational(3, 1073741789) + Rational(1073741827, 1))
+    assert_equal(Rational(-1152921470247108500, 1073741789),
+                 Rational(3, 1073741789) - Rational(1073741827, 1))
+    assert_equal(Rational(3221225481, 1073741789),
+                 Rational(3, 1073741789) * Rational(1073741827, 1))
+    assert_equal(Rational(3, 1152921470247108503),
+                 Rational(3, 1073741789) / Rational(1073741827, 1))
+    assert_equal(Rational(2147483587, 3221225367),
+                 Rational(3, 1073741789) + Rational(2, 3))
+    assert_equal(Rational(-2147483569, 3221225367),
+                 Rational(3, 1073741789) - Rational(2, 3))
+    assert_equal(Rational(2, 1073741789),
+                 Rational(3, 1073741789) * Rational(2, 3))
+    assert_equal(Rational(9, 2147483578),
+                 Rational(3, 1073741789) / Rational(2, 3))
+    assert_equal(Rational(3221225373, 2147483578),
+                 Rational(3, 1073741789) + Rational(3, 2))
+    assert_equal(Rational(-3221225361, 2147483578),
+                 Rational(3, 1073741789) - Rational(3, 2))
+    assert_equal(Rational(9, 2147483578),
+                 Rational(3, 1073741789) * Rational(3, 2))
+    assert_equal(Rational(2, 1073741789),
+                 Rational(3, 1073741789) / Rational(3, 2))
+    assert_equal(Rational(6, 1073741789),
+                 Rational(3, 1073741789) + Rational(3, 1073741789))
+    assert_equal(Rational(0, 1),
+                 Rational(3, 1073741789) - Rational(3, 1073741789))
+    assert_equal(Rational(9, 1152921429444920521),
+                 Rational(3, 1073741789) * Rational(3, 1073741789))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 1073741789) / Rational(3, 1073741789))
+    assert_equal(Rational(1152921429444920530, 3221225367),
+                 Rational(3, 1073741789) + Rational(1073741789, 3))
+    assert_equal(Rational(-1152921429444920512, 3221225367),
+                 Rational(3, 1073741789) - Rational(1073741789, 3))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 1073741789) * Rational(1073741789, 3))
+    assert_equal(Rational(9, 1152921429444920521),
+                 Rational(3, 1073741789) / Rational(1073741789, 3))
+    assert_equal(Rational(6442450848, 1152921470247108503),
+                 Rational(3, 1073741789) + Rational(3, 1073741827))
+    assert_equal(Rational(114, 1152921470247108503),
+                 Rational(3, 1073741789) - Rational(3, 1073741827))
+    assert_equal(Rational(9, 1152921470247108503),
+                 Rational(3, 1073741789) * Rational(3, 1073741827))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(3, 1073741789) / Rational(3, 1073741827))
+    assert_equal(Rational(1152921470247108512, 3221225367),
+                 Rational(3, 1073741789) + Rational(1073741827, 3))
+    assert_equal(Rational(-1152921470247108494, 3221225367),
+                 Rational(3, 1073741789) - Rational(1073741827, 3))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(3, 1073741789) * Rational(1073741827, 3))
+    assert_equal(Rational(9, 1152921470247108503),
+                 Rational(3, 1073741789) / Rational(1073741827, 3))
+    assert_equal(Rational(1152921432666146002, 1152921470247108503),
+                 Rational(3, 1073741789) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(-1152921426223695040, 1152921470247108503),
+                 Rational(3, 1073741789) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(3, 1073741789) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(3221225481, 1152921429444920521),
+                 Rational(3, 1073741789) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741830, 1073741789),
+                 Rational(3, 1073741789) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(-1073741824, 1073741789),
+                 Rational(3, 1073741789) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(3221225481, 1152921429444920521),
+                 Rational(3, 1073741789) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(3, 1073741789) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741792, 3),
+                 Rational(1073741789, 3) + Rational(1, 1))
+    assert_equal(Rational(1073741786, 3),
+                 Rational(1073741789, 3) - Rational(1, 1))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1073741789, 3) * Rational(1, 1))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1073741789, 3) / Rational(1, 1))
+    assert_equal(Rational(1073741795, 3),
+                 Rational(1073741789, 3) + Rational(2, 1))
+    assert_equal(Rational(1073741783, 3),
+                 Rational(1073741789, 3) - Rational(2, 1))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(1073741789, 3) * Rational(2, 1))
+    assert_equal(Rational(1073741789, 6),
+                 Rational(1073741789, 3) / Rational(2, 1))
+    assert_equal(Rational(1073741798, 3),
+                 Rational(1073741789, 3) + Rational(3, 1))
+    assert_equal(Rational(1073741780, 3),
+                 Rational(1073741789, 3) - Rational(3, 1))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(1073741789, 3) * Rational(3, 1))
+    assert_equal(Rational(1073741789, 9),
+                 Rational(1073741789, 3) / Rational(3, 1))
+    assert_equal(Rational(4294967156, 3),
+                 Rational(1073741789, 3) + Rational(1073741789, 1))
+    assert_equal(Rational(-2147483578, 3),
+                 Rational(1073741789, 3) - Rational(1073741789, 1))
+    assert_equal(Rational(1152921429444920521, 3),
+                 Rational(1073741789, 3) * Rational(1073741789, 1))
+    assert_equal(Rational(1, 3),
+                 Rational(1073741789, 3) / Rational(1073741789, 1))
+    assert_equal(Rational(4294967270, 3),
+                 Rational(1073741789, 3) + Rational(1073741827, 1))
+    assert_equal(Rational(-2147483692, 3),
+                 Rational(1073741789, 3) - Rational(1073741827, 1))
+    assert_equal(Rational(1152921470247108503, 3),
+                 Rational(1073741789, 3) * Rational(1073741827, 1))
+    assert_equal(Rational(1073741789, 3221225481),
+                 Rational(1073741789, 3) / Rational(1073741827, 1))
+    assert_equal(Rational(1073741791, 3),
+                 Rational(1073741789, 3) + Rational(2, 3))
+    assert_equal(Rational(357913929, 1),
+                 Rational(1073741789, 3) - Rational(2, 3))
+    assert_equal(Rational(2147483578, 9),
+                 Rational(1073741789, 3) * Rational(2, 3))
+    assert_equal(Rational(1073741789, 2),
+                 Rational(1073741789, 3) / Rational(2, 3))
+    assert_equal(Rational(2147483587, 6),
+                 Rational(1073741789, 3) + Rational(3, 2))
+    assert_equal(Rational(2147483569, 6),
+                 Rational(1073741789, 3) - Rational(3, 2))
+    assert_equal(Rational(1073741789, 2),
+                 Rational(1073741789, 3) * Rational(3, 2))
+    assert_equal(Rational(2147483578, 9),
+                 Rational(1073741789, 3) / Rational(3, 2))
+    assert_equal(Rational(1152921429444920530, 3221225367),
+                 Rational(1073741789, 3) + Rational(3, 1073741789))
+    assert_equal(Rational(1152921429444920512, 3221225367),
+                 Rational(1073741789, 3) - Rational(3, 1073741789))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741789, 3) * Rational(3, 1073741789))
+    assert_equal(Rational(1152921429444920521, 9),
+                 Rational(1073741789, 3) / Rational(3, 1073741789))
+    assert_equal(Rational(2147483578, 3),
+                 Rational(1073741789, 3) + Rational(1073741789, 3))
+    assert_equal(Rational(0, 1),
+                 Rational(1073741789, 3) - Rational(1073741789, 3))
+    assert_equal(Rational(1152921429444920521, 9),
+                 Rational(1073741789, 3) * Rational(1073741789, 3))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741789, 3) / Rational(1073741789, 3))
+    assert_equal(Rational(1152921470247108512, 3221225481),
+                 Rational(1073741789, 3) + Rational(3, 1073741827))
+    assert_equal(Rational(1152921470247108494, 3221225481),
+                 Rational(1073741789, 3) - Rational(3, 1073741827))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(1073741789, 3) * Rational(3, 1073741827))
+    assert_equal(Rational(1152921470247108503, 9),
+                 Rational(1073741789, 3) / Rational(3, 1073741827))
+    assert_equal(Rational(715827872, 1),
+                 Rational(1073741789, 3) + Rational(1073741827, 3))
+    assert_equal(Rational(-38, 3),
+                 Rational(1073741789, 3) - Rational(1073741827, 3))
+    assert_equal(Rational(1152921470247108503, 9),
+                 Rational(1073741789, 3) * Rational(1073741827, 3))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(1073741789, 3) / Rational(1073741827, 3))
+    assert_equal(Rational(1152921473468333870, 3221225481),
+                 Rational(1073741789, 3) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921467025883136, 3221225481),
+                 Rational(1073741789, 3) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921429444920521, 3221225481),
+                 Rational(1073741789, 3) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1073741789, 3) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921432666146002, 3221225367),
+                 Rational(1073741789, 3) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921426223695040, 3221225367),
+                 Rational(1073741789, 3) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1073741789, 3) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921429444920521, 3221225481),
+                 Rational(1073741789, 3) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741830, 1073741827),
+                 Rational(3, 1073741827) + Rational(1, 1))
+    assert_equal(Rational(-1073741824, 1073741827),
+                 Rational(3, 1073741827) - Rational(1, 1))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(3, 1073741827) * Rational(1, 1))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(3, 1073741827) / Rational(1, 1))
+    assert_equal(Rational(2147483657, 1073741827),
+                 Rational(3, 1073741827) + Rational(2, 1))
+    assert_equal(Rational(-2147483651, 1073741827),
+                 Rational(3, 1073741827) - Rational(2, 1))
+    assert_equal(Rational(6, 1073741827),
+                 Rational(3, 1073741827) * Rational(2, 1))
+    assert_equal(Rational(3, 2147483654),
+                 Rational(3, 1073741827) / Rational(2, 1))
+    assert_equal(Rational(3221225484, 1073741827),
+                 Rational(3, 1073741827) + Rational(3, 1))
+    assert_equal(Rational(-3221225478, 1073741827),
+                 Rational(3, 1073741827) - Rational(3, 1))
+    assert_equal(Rational(9, 1073741827),
+                 Rational(3, 1073741827) * Rational(3, 1))
+    assert_equal(Rational(1, 1073741827),
+                 Rational(3, 1073741827) / Rational(3, 1))
+    assert_equal(Rational(1152921470247108506, 1073741827),
+                 Rational(3, 1073741827) + Rational(1073741789, 1))
+    assert_equal(Rational(-1152921470247108500, 1073741827),
+                 Rational(3, 1073741827) - Rational(1073741789, 1))
+    assert_equal(Rational(3221225367, 1073741827),
+                 Rational(3, 1073741827) * Rational(1073741789, 1))
+    assert_equal(Rational(3, 1152921470247108503),
+                 Rational(3, 1073741827) / Rational(1073741789, 1))
+    assert_equal(Rational(1152921511049297932, 1073741827),
+                 Rational(3, 1073741827) + Rational(1073741827, 1))
+    assert_equal(Rational(-1152921511049297926, 1073741827),
+                 Rational(3, 1073741827) - Rational(1073741827, 1))
+    assert_equal(Rational(3, 1),
+                 Rational(3, 1073741827) * Rational(1073741827, 1))
+    assert_equal(Rational(3, 1152921511049297929),
+                 Rational(3, 1073741827) / Rational(1073741827, 1))
+    assert_equal(Rational(2147483663, 3221225481),
+                 Rational(3, 1073741827) + Rational(2, 3))
+    assert_equal(Rational(-2147483645, 3221225481),
+                 Rational(3, 1073741827) - Rational(2, 3))
+    assert_equal(Rational(2, 1073741827),
+                 Rational(3, 1073741827) * Rational(2, 3))
+    assert_equal(Rational(9, 2147483654),
+                 Rational(3, 1073741827) / Rational(2, 3))
+    assert_equal(Rational(3221225487, 2147483654),
+                 Rational(3, 1073741827) + Rational(3, 2))
+    assert_equal(Rational(-3221225475, 2147483654),
+                 Rational(3, 1073741827) - Rational(3, 2))
+    assert_equal(Rational(9, 2147483654),
+                 Rational(3, 1073741827) * Rational(3, 2))
+    assert_equal(Rational(2, 1073741827),
+                 Rational(3, 1073741827) / Rational(3, 2))
+    assert_equal(Rational(6442450848, 1152921470247108503),
+                 Rational(3, 1073741827) + Rational(3, 1073741789))
+    assert_equal(Rational(-114, 1152921470247108503),
+                 Rational(3, 1073741827) - Rational(3, 1073741789))
+    assert_equal(Rational(9, 1152921470247108503),
+                 Rational(3, 1073741827) * Rational(3, 1073741789))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(3, 1073741827) / Rational(3, 1073741789))
+    assert_equal(Rational(1152921470247108512, 3221225481),
+                 Rational(3, 1073741827) + Rational(1073741789, 3))
+    assert_equal(Rational(-1152921470247108494, 3221225481),
+                 Rational(3, 1073741827) - Rational(1073741789, 3))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(3, 1073741827) * Rational(1073741789, 3))
+    assert_equal(Rational(9, 1152921470247108503),
+                 Rational(3, 1073741827) / Rational(1073741789, 3))
+    assert_equal(Rational(6, 1073741827),
+                 Rational(3, 1073741827) + Rational(3, 1073741827))
+    assert_equal(Rational(0, 1),
+                 Rational(3, 1073741827) - Rational(3, 1073741827))
+    assert_equal(Rational(9, 1152921511049297929),
+                 Rational(3, 1073741827) * Rational(3, 1073741827))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 1073741827) / Rational(3, 1073741827))
+    assert_equal(Rational(1152921511049297938, 3221225481),
+                 Rational(3, 1073741827) + Rational(1073741827, 3))
+    assert_equal(Rational(-1152921511049297920, 3221225481),
+                 Rational(3, 1073741827) - Rational(1073741827, 3))
+    assert_equal(Rational(1, 1),
+                 Rational(3, 1073741827) * Rational(1073741827, 3))
+    assert_equal(Rational(9, 1152921511049297929),
+                 Rational(3, 1073741827) / Rational(1073741827, 3))
+    assert_equal(Rational(1073741792, 1073741827),
+                 Rational(3, 1073741827) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(-1073741786, 1073741827),
+                 Rational(3, 1073741827) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(3221225367, 1152921511049297929),
+                 Rational(3, 1073741827) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(3, 1073741827) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921514270523296, 1152921470247108503),
+                 Rational(3, 1073741827) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(-1152921507828072562, 1152921470247108503),
+                 Rational(3, 1073741827) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(3, 1073741827) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(3221225367, 1152921511049297929),
+                 Rational(3, 1073741827) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741830, 3),
+                 Rational(1073741827, 3) + Rational(1, 1))
+    assert_equal(Rational(1073741824, 3),
+                 Rational(1073741827, 3) - Rational(1, 1))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1073741827, 3) * Rational(1, 1))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1073741827, 3) / Rational(1, 1))
+    assert_equal(Rational(1073741833, 3),
+                 Rational(1073741827, 3) + Rational(2, 1))
+    assert_equal(Rational(1073741821, 3),
+                 Rational(1073741827, 3) - Rational(2, 1))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(1073741827, 3) * Rational(2, 1))
+    assert_equal(Rational(1073741827, 6),
+                 Rational(1073741827, 3) / Rational(2, 1))
+    assert_equal(Rational(1073741836, 3),
+                 Rational(1073741827, 3) + Rational(3, 1))
+    assert_equal(Rational(1073741818, 3),
+                 Rational(1073741827, 3) - Rational(3, 1))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(1073741827, 3) * Rational(3, 1))
+    assert_equal(Rational(1073741827, 9),
+                 Rational(1073741827, 3) / Rational(3, 1))
+    assert_equal(Rational(4294967194, 3),
+                 Rational(1073741827, 3) + Rational(1073741789, 1))
+    assert_equal(Rational(-2147483540, 3),
+                 Rational(1073741827, 3) - Rational(1073741789, 1))
+    assert_equal(Rational(1152921470247108503, 3),
+                 Rational(1073741827, 3) * Rational(1073741789, 1))
+    assert_equal(Rational(1073741827, 3221225367),
+                 Rational(1073741827, 3) / Rational(1073741789, 1))
+    assert_equal(Rational(4294967308, 3),
+                 Rational(1073741827, 3) + Rational(1073741827, 1))
+    assert_equal(Rational(-2147483654, 3),
+                 Rational(1073741827, 3) - Rational(1073741827, 1))
+    assert_equal(Rational(1152921511049297929, 3),
+                 Rational(1073741827, 3) * Rational(1073741827, 1))
+    assert_equal(Rational(1, 3),
+                 Rational(1073741827, 3) / Rational(1073741827, 1))
+    assert_equal(Rational(357913943, 1),
+                 Rational(1073741827, 3) + Rational(2, 3))
+    assert_equal(Rational(1073741825, 3),
+                 Rational(1073741827, 3) - Rational(2, 3))
+    assert_equal(Rational(2147483654, 9),
+                 Rational(1073741827, 3) * Rational(2, 3))
+    assert_equal(Rational(1073741827, 2),
+                 Rational(1073741827, 3) / Rational(2, 3))
+    assert_equal(Rational(2147483663, 6),
+                 Rational(1073741827, 3) + Rational(3, 2))
+    assert_equal(Rational(2147483645, 6),
+                 Rational(1073741827, 3) - Rational(3, 2))
+    assert_equal(Rational(1073741827, 2),
+                 Rational(1073741827, 3) * Rational(3, 2))
+    assert_equal(Rational(2147483654, 9),
+                 Rational(1073741827, 3) / Rational(3, 2))
+    assert_equal(Rational(1152921470247108512, 3221225367),
+                 Rational(1073741827, 3) + Rational(3, 1073741789))
+    assert_equal(Rational(1152921470247108494, 3221225367),
+                 Rational(1073741827, 3) - Rational(3, 1073741789))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(1073741827, 3) * Rational(3, 1073741789))
+    assert_equal(Rational(1152921470247108503, 9),
+                 Rational(1073741827, 3) / Rational(3, 1073741789))
+    assert_equal(Rational(715827872, 1),
+                 Rational(1073741827, 3) + Rational(1073741789, 3))
+    assert_equal(Rational(38, 3),
+                 Rational(1073741827, 3) - Rational(1073741789, 3))
+    assert_equal(Rational(1152921470247108503, 9),
+                 Rational(1073741827, 3) * Rational(1073741789, 3))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(1073741827, 3) / Rational(1073741789, 3))
+    assert_equal(Rational(1152921511049297938, 3221225481),
+                 Rational(1073741827, 3) + Rational(3, 1073741827))
+    assert_equal(Rational(1152921511049297920, 3221225481),
+                 Rational(1073741827, 3) - Rational(3, 1073741827))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741827, 3) * Rational(3, 1073741827))
+    assert_equal(Rational(1152921511049297929, 9),
+                 Rational(1073741827, 3) / Rational(3, 1073741827))
+    assert_equal(Rational(2147483654, 3),
+                 Rational(1073741827, 3) + Rational(1073741827, 3))
+    assert_equal(Rational(0, 1),
+                 Rational(1073741827, 3) - Rational(1073741827, 3))
+    assert_equal(Rational(1152921511049297929, 9),
+                 Rational(1073741827, 3) * Rational(1073741827, 3))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741827, 3) / Rational(1073741827, 3))
+    assert_equal(Rational(1152921514270523296, 3221225481),
+                 Rational(1073741827, 3) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921507828072562, 3221225481),
+                 Rational(1073741827, 3) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1073741827, 3) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921511049297929, 3221225367),
+                 Rational(1073741827, 3) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921473468333984, 3221225367),
+                 Rational(1073741827, 3) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921467025883022, 3221225367),
+                 Rational(1073741827, 3) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921511049297929, 3221225367),
+                 Rational(1073741827, 3) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1073741827, 3) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(2147483616, 1073741827),
+                 Rational(1073741789, 1073741827) + Rational(1, 1))
+    assert_equal(Rational(-38, 1073741827),
+                 Rational(1073741789, 1073741827) - Rational(1, 1))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(1073741789, 1073741827) * Rational(1, 1))
+    assert_equal(Rational(1073741789, 1073741827),
+                 Rational(1073741789, 1073741827) / Rational(1, 1))
+    assert_equal(Rational(3221225443, 1073741827),
+                 Rational(1073741789, 1073741827) + Rational(2, 1))
+    assert_equal(Rational(-1073741865, 1073741827),
+                 Rational(1073741789, 1073741827) - Rational(2, 1))
+    assert_equal(Rational(2147483578, 1073741827),
+                 Rational(1073741789, 1073741827) * Rational(2, 1))
+    assert_equal(Rational(1073741789, 2147483654),
+                 Rational(1073741789, 1073741827) / Rational(2, 1))
+    assert_equal(Rational(4294967270, 1073741827),
+                 Rational(1073741789, 1073741827) + Rational(3, 1))
+    assert_equal(Rational(-2147483692, 1073741827),
+                 Rational(1073741789, 1073741827) - Rational(3, 1))
+    assert_equal(Rational(3221225367, 1073741827),
+                 Rational(1073741789, 1073741827) * Rational(3, 1))
+    assert_equal(Rational(1073741789, 3221225481),
+                 Rational(1073741789, 1073741827) / Rational(3, 1))
+    assert_equal(Rational(1152921471320850292, 1073741827),
+                 Rational(1073741789, 1073741827) + Rational(1073741789, 1))
+    assert_equal(Rational(-1152921469173366714, 1073741827),
+                 Rational(1073741789, 1073741827) - Rational(1073741789, 1))
+    assert_equal(Rational(1152921429444920521, 1073741827),
+                 Rational(1073741789, 1073741827) * Rational(1073741789, 1))
+    assert_equal(Rational(1, 1073741827),
+                 Rational(1073741789, 1073741827) / Rational(1073741789, 1))
+    assert_equal(Rational(1152921512123039718, 1073741827),
+                 Rational(1073741789, 1073741827) + Rational(1073741827, 1))
+    assert_equal(Rational(-1152921509975556140, 1073741827),
+                 Rational(1073741789, 1073741827) - Rational(1073741827, 1))
+    assert_equal(Rational(1073741789, 1),
+                 Rational(1073741789, 1073741827) * Rational(1073741827, 1))
+    assert_equal(Rational(1073741789, 1152921511049297929),
+                 Rational(1073741789, 1073741827) / Rational(1073741827, 1))
+    assert_equal(Rational(5368709021, 3221225481),
+                 Rational(1073741789, 1073741827) + Rational(2, 3))
+    assert_equal(Rational(1073741713, 3221225481),
+                 Rational(1073741789, 1073741827) - Rational(2, 3))
+    assert_equal(Rational(2147483578, 3221225481),
+                 Rational(1073741789, 1073741827) * Rational(2, 3))
+    assert_equal(Rational(3221225367, 2147483654),
+                 Rational(1073741789, 1073741827) / Rational(2, 3))
+    assert_equal(Rational(5368709059, 2147483654),
+                 Rational(1073741789, 1073741827) + Rational(3, 2))
+    assert_equal(Rational(-1073741903, 2147483654),
+                 Rational(1073741789, 1073741827) - Rational(3, 2))
+    assert_equal(Rational(3221225367, 2147483654),
+                 Rational(1073741789, 1073741827) * Rational(3, 2))
+    assert_equal(Rational(2147483578, 3221225481),
+                 Rational(1073741789, 1073741827) / Rational(3, 2))
+    assert_equal(Rational(1152921432666146002, 1152921470247108503),
+                 Rational(1073741789, 1073741827) + Rational(3, 1073741789))
+    assert_equal(Rational(1152921426223695040, 1152921470247108503),
+                 Rational(1073741789, 1073741827) - Rational(3, 1073741789))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(1073741789, 1073741827) * Rational(3, 1073741789))
+    assert_equal(Rational(1152921429444920521, 3221225481),
+                 Rational(1073741789, 1073741827) / Rational(3, 1073741789))
+    assert_equal(Rational(1152921473468333870, 3221225481),
+                 Rational(1073741789, 1073741827) + Rational(1073741789, 3))
+    assert_equal(Rational(-1152921467025883136, 3221225481),
+                 Rational(1073741789, 1073741827) - Rational(1073741789, 3))
+    assert_equal(Rational(1152921429444920521, 3221225481),
+                 Rational(1073741789, 1073741827) * Rational(1073741789, 3))
+    assert_equal(Rational(3, 1073741827),
+                 Rational(1073741789, 1073741827) / Rational(1073741789, 3))
+    assert_equal(Rational(1073741792, 1073741827),
+                 Rational(1073741789, 1073741827) + Rational(3, 1073741827))
+    assert_equal(Rational(1073741786, 1073741827),
+                 Rational(1073741789, 1073741827) - Rational(3, 1073741827))
+    assert_equal(Rational(3221225367, 1152921511049297929),
+                 Rational(1073741789, 1073741827) * Rational(3, 1073741827))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1073741789, 1073741827) / Rational(3, 1073741827))
+    assert_equal(Rational(1152921514270523296, 3221225481),
+                 Rational(1073741789, 1073741827) + Rational(1073741827, 3))
+    assert_equal(Rational(-1152921507828072562, 3221225481),
+                 Rational(1073741789, 1073741827) - Rational(1073741827, 3))
+    assert_equal(Rational(1073741789, 3),
+                 Rational(1073741789, 1073741827) * Rational(1073741827, 3))
+    assert_equal(Rational(3221225367, 1152921511049297929),
+                 Rational(1073741789, 1073741827) / Rational(1073741827, 3))
+    assert_equal(Rational(2147483578, 1073741827),
+                 Rational(1073741789, 1073741827) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(0, 1),
+                 Rational(1073741789, 1073741827) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921429444920521, 1152921511049297929),
+                 Rational(1073741789, 1073741827) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741789, 1073741827) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(2305842940494218450, 1152921470247108503),
+                 Rational(1073741789, 1073741827) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(-81604377408, 1152921470247108503),
+                 Rational(1073741789, 1073741827) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741789, 1073741827) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921429444920521, 1152921511049297929),
+                 Rational(1073741789, 1073741827) / Rational(1073741827, 1073741789))
+    assert_equal(Rational(2147483616, 1073741789),
+                 Rational(1073741827, 1073741789) + Rational(1, 1))
+    assert_equal(Rational(38, 1073741789),
+                 Rational(1073741827, 1073741789) - Rational(1, 1))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(1073741827, 1073741789) * Rational(1, 1))
+    assert_equal(Rational(1073741827, 1073741789),
+                 Rational(1073741827, 1073741789) / Rational(1, 1))
+    assert_equal(Rational(3221225405, 1073741789),
+                 Rational(1073741827, 1073741789) + Rational(2, 1))
+    assert_equal(Rational(-1073741751, 1073741789),
+                 Rational(1073741827, 1073741789) - Rational(2, 1))
+    assert_equal(Rational(2147483654, 1073741789),
+                 Rational(1073741827, 1073741789) * Rational(2, 1))
+    assert_equal(Rational(1073741827, 2147483578),
+                 Rational(1073741827, 1073741789) / Rational(2, 1))
+    assert_equal(Rational(4294967194, 1073741789),
+                 Rational(1073741827, 1073741789) + Rational(3, 1))
+    assert_equal(Rational(-2147483540, 1073741789),
+                 Rational(1073741827, 1073741789) - Rational(3, 1))
+    assert_equal(Rational(3221225481, 1073741789),
+                 Rational(1073741827, 1073741789) * Rational(3, 1))
+    assert_equal(Rational(1073741827, 3221225367),
+                 Rational(1073741827, 1073741789) / Rational(3, 1))
+    assert_equal(Rational(1152921430518662348, 1073741789),
+                 Rational(1073741827, 1073741789) + Rational(1073741789, 1))
+    assert_equal(Rational(-1152921428371178694, 1073741789),
+                 Rational(1073741827, 1073741789) - Rational(1073741789, 1))
+    assert_equal(Rational(1073741827, 1),
+                 Rational(1073741827, 1073741789) * Rational(1073741789, 1))
+    assert_equal(Rational(1073741827, 1152921429444920521),
+                 Rational(1073741827, 1073741789) / Rational(1073741789, 1))
+    assert_equal(Rational(1152921471320850330, 1073741789),
+                 Rational(1073741827, 1073741789) + Rational(1073741827, 1))
+    assert_equal(Rational(-1152921469173366676, 1073741789),
+                 Rational(1073741827, 1073741789) - Rational(1073741827, 1))
+    assert_equal(Rational(1152921511049297929, 1073741789),
+                 Rational(1073741827, 1073741789) * Rational(1073741827, 1))
+    assert_equal(Rational(1, 1073741789),
+                 Rational(1073741827, 1073741789) / Rational(1073741827, 1))
+    assert_equal(Rational(5368709059, 3221225367),
+                 Rational(1073741827, 1073741789) + Rational(2, 3))
+    assert_equal(Rational(1073741903, 3221225367),
+                 Rational(1073741827, 1073741789) - Rational(2, 3))
+    assert_equal(Rational(2147483654, 3221225367),
+                 Rational(1073741827, 1073741789) * Rational(2, 3))
+    assert_equal(Rational(3221225481, 2147483578),
+                 Rational(1073741827, 1073741789) / Rational(2, 3))
+    assert_equal(Rational(5368709021, 2147483578),
+                 Rational(1073741827, 1073741789) + Rational(3, 2))
+    assert_equal(Rational(-1073741713, 2147483578),
+                 Rational(1073741827, 1073741789) - Rational(3, 2))
+    assert_equal(Rational(3221225481, 2147483578),
+                 Rational(1073741827, 1073741789) * Rational(3, 2))
+    assert_equal(Rational(2147483654, 3221225367),
+                 Rational(1073741827, 1073741789) / Rational(3, 2))
+    assert_equal(Rational(1073741830, 1073741789),
+                 Rational(1073741827, 1073741789) + Rational(3, 1073741789))
+    assert_equal(Rational(1073741824, 1073741789),
+                 Rational(1073741827, 1073741789) - Rational(3, 1073741789))
+    assert_equal(Rational(3221225481, 1152921429444920521),
+                 Rational(1073741827, 1073741789) * Rational(3, 1073741789))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1073741827, 1073741789) / Rational(3, 1073741789))
+    assert_equal(Rational(1152921432666146002, 3221225367),
+                 Rational(1073741827, 1073741789) + Rational(1073741789, 3))
+    assert_equal(Rational(-1152921426223695040, 3221225367),
+                 Rational(1073741827, 1073741789) - Rational(1073741789, 3))
+    assert_equal(Rational(1073741827, 3),
+                 Rational(1073741827, 1073741789) * Rational(1073741789, 3))
+    assert_equal(Rational(3221225481, 1152921429444920521),
+                 Rational(1073741827, 1073741789) / Rational(1073741789, 3))
+    assert_equal(Rational(1152921514270523296, 1152921470247108503),
+                 Rational(1073741827, 1073741789) + Rational(3, 1073741827))
+    assert_equal(Rational(1152921507828072562, 1152921470247108503),
+                 Rational(1073741827, 1073741789) - Rational(3, 1073741827))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(1073741827, 1073741789) * Rational(3, 1073741827))
+    assert_equal(Rational(1152921511049297929, 3221225367),
+                 Rational(1073741827, 1073741789) / Rational(3, 1073741827))
+    assert_equal(Rational(1152921473468333984, 3221225367),
+                 Rational(1073741827, 1073741789) + Rational(1073741827, 3))
+    assert_equal(Rational(-1152921467025883022, 3221225367),
+                 Rational(1073741827, 1073741789) - Rational(1073741827, 3))
+    assert_equal(Rational(1152921511049297929, 3221225367),
+                 Rational(1073741827, 1073741789) * Rational(1073741827, 3))
+    assert_equal(Rational(3, 1073741789),
+                 Rational(1073741827, 1073741789) / Rational(1073741827, 3))
+    assert_equal(Rational(2305842940494218450, 1152921470247108503),
+                 Rational(1073741827, 1073741789) + Rational(1073741789, 1073741827))
+    assert_equal(Rational(81604377408, 1152921470247108503),
+                 Rational(1073741827, 1073741789) - Rational(1073741789, 1073741827))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741827, 1073741789) * Rational(1073741789, 1073741827))
+    assert_equal(Rational(1152921511049297929, 1152921429444920521),
+                 Rational(1073741827, 1073741789) / Rational(1073741789, 1073741827))
+    assert_equal(Rational(2147483654, 1073741789),
+                 Rational(1073741827, 1073741789) + Rational(1073741827, 1073741789))
+    assert_equal(Rational(0, 1),
+                 Rational(1073741827, 1073741789) - Rational(1073741827, 1073741789))
+    assert_equal(Rational(1152921511049297929, 1152921429444920521),
+                 Rational(1073741827, 1073741789) * Rational(1073741827, 1073741789))
+    assert_equal(Rational(1, 1),
+                 Rational(1073741827, 1073741789) / Rational(1073741827, 1073741789))
+  end
+
+end

Property changes on: test/ruby/test_rational2.rb
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Index: rational.c
===================================================================
--- rational.c	(revision 15811)
+++ rational.c	(revision 15812)
@@ -25,39 +25,237 @@
   id_floor, id_format,id_idiv, id_inspect, id_negate, id_new, id_new_bang,
   id_to_f, id_to_i, id_to_s, id_truncate;
 
-#define f_add(x,y) rb_funcall(x, '+', 1, y)
-#define f_div(x,y) rb_funcall(x, '/', 1, y)
-#define f_gt_p(x,y) rb_funcall(x, '>', 1, y)
-#define f_lt_p(x,y) rb_funcall(x, '<', 1, y)
-#define f_mod(x,y) rb_funcall(x, '%', 1, y)
-#define f_mul(x,y) rb_funcall(x, '*', 1, y)
-#define f_sub(x,y) rb_funcall(x, '-', 1, y)
-#define f_xor(x,y) rb_funcall(x, '^', 1, y)
+#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
 
-#define f_floor(x) rb_funcall(x, id_floor, 0)
-#define f_inspect(x) rb_funcall(x, id_inspect, 0)
-#define f_to_f(x) rb_funcall(x, id_to_f, 0)
-#define f_to_i(x) rb_funcall(x, id_to_i, 0)
-#define f_to_s(x) rb_funcall(x, id_to_s, 0)
-#define f_truncate(x) rb_funcall(x, id_truncate, 0)
-#define f_cmp(x,y) rb_funcall(x, id_cmp, 1, y)
-#define f_coerce(x,y) rb_funcall(x, id_coerce, 1, y)
-#define f_equal_p(x,y) rb_funcall(x, id_equal_p, 1, y)
-#define f_expt(x,y) rb_funcall(x, id_expt, 1, y)
-#define f_idiv(x,y) rb_funcall(x, id_idiv, 1, y)
-#define f_negate(x) rb_funcall(x, id_negate, 0)
+#define binop(n,op) \
+inline static VALUE \
+f_##n(VALUE x, VALUE y)\
+{\
+  return rb_funcall(x, op, 1, y);\
+}
 
-#define f_negative_p(x) f_lt_p(x, ZERO)
-#define f_zero_p(x) f_equal_p(x, ZERO)
-#define f_one_p(x) f_equal_p(x, ONE)
-#define f_kind_of_p(x,c) rb_obj_is_kind_of(x, c)
-#define k_numeric_p(x) f_kind_of_p(x, rb_cNumeric)
-#define k_integer_p(x) f_kind_of_p(x, rb_cInteger)
-#define k_float_p(x) f_kind_of_p(x, rb_cFloat)
-#define k_rational_p(x) f_kind_of_p(x, rb_cRational)
+#define fun1(n) \
+inline static VALUE \
+f_##n(VALUE x)\
+{\
+  return rb_funcall(x, id_##n, 0);\
+}
 
-#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
+#define fun2(n) \
+inline static VALUE \
+f_##n(VALUE x, VALUE y)\
+{\
+  return rb_funcall(x, id_##n, 1, y);\
+}
 
+inline static VALUE
+f_add(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(y)) {
+     if (FIX2INT(y) == 0)
+       _r = x;
+     else
+       _r = rb_funcall(x, '+', 1, y);
+   } else if (FIXNUM_P(x)) {
+     if (FIX2INT(x) == 0)
+       _r = y;
+     else
+       _r = rb_funcall(x, '+', 1, y);
+   } else
+     _r = rb_funcall(x, '+', 1, y);
+   return _r;
+}
+
+inline static VALUE
+f_div(x, y)
+{
+  VALUE _r;
+  if (FIXNUM_P(y) && FIX2INT(y) == 1)
+    _r = x;
+   else
+     _r = rb_funcall(x, '/', 1, y);
+  return _r;
+}
+
+inline static VALUE
+f_gt_p(VALUE x, VALUE y)
+{
+   VALUE _r;
+  if (FIXNUM_P(x) && FIXNUM_P(y))
+    _r = f_boolcast(FIX2INT(x) > FIX2INT(y));
+  else
+    _r = rb_funcall(x, '>', 1, y);
+  return _r;
+}
+
+inline static VALUE
+f_lt_p(VALUE x, VALUE y)
+{
+   VALUE _r;
+  if (FIXNUM_P(x) && FIXNUM_P(y))
+    _r = f_boolcast(FIX2INT(x) < FIX2INT(y));
+  else
+    _r = rb_funcall(x, '<', 1, y);
+  return _r;
+}
+
+binop(mod, '%')
+
+inline static VALUE
+f_mul(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(y)) {
+     int _iy = FIX2INT(y);
+     if (_iy == 0) {
+       if (TYPE(x) == T_FLOAT)
+	 _r = rb_float_new(0.0);
+       else
+	 _r = ZERO;
+     } else if (_iy == 1)
+       _r = x;
+     else
+       _r = rb_funcall(x, '*', 1, y);
+   } else if (FIXNUM_P(x)) {
+     int _ix = FIX2INT(x);
+     if (_ix == 0) {
+       if (TYPE(y) == T_FLOAT)
+	 _r = rb_float_new(0.0);
+       else
+	 _r = ZERO;
+     } else if (_ix == 1)
+       _r = y;
+     else
+       _r = rb_funcall(x, '*', 1, y);
+   } else
+     _r = rb_funcall(x, '*', 1, y);
+   return _r;
+}
+
+inline static VALUE
+f_sub(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(y)) {
+     if (FIX2INT(y) == 0)
+       _r = x;
+     else
+       _r = rb_funcall(x, '-', 1, y);
+   } else
+    _r = rb_funcall(x, '-', 1, y);
+   return _r;
+}
+
+binop(xor, '^')
+
+fun1(floor)
+fun1(inspect)
+fun1(negate)
+fun1(to_f)
+fun1(to_i)
+fun1(to_s)
+fun1(truncate)
+
+inline static VALUE
+f_cmp(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(x) && FIXNUM_P(y)) {
+     int c = FIX2INT(x) - FIX2INT(y);
+     if (c > 0)
+       c = 1;
+     else if (c < 0)
+       c = -1;
+     _r = INT2FIX(c);
+   } else
+     _r = rb_funcall(x, id_cmp, 1, y);
+   return _r;
+}
+
+fun2(coerce)
+
+inline static VALUE
+f_equal_p(VALUE x, VALUE y)
+{
+   VALUE _r;
+   if (FIXNUM_P(x) && FIXNUM_P(y))
+     _r = f_boolcast(FIX2INT(x) == FIX2INT(y));
+   else
+     _r = rb_funcall(x, id_equal_p, 1, y);
+   return _r;
+}
+
+fun2(expt)
+fun2(idiv)
+
+inline static VALUE
+f_negative_p(VALUE x)
+{
+   VALUE _r;
+  if (FIXNUM_P(x))
+    _r = f_boolcast(FIX2INT(x) < 0);
+  else
+    _r = rb_funcall(x, '<', 1, ZERO);
+  return _r;
+}
+
+inline static VALUE
+f_zero_p(VALUE x)
+{
+   VALUE _r;
+   if (FIXNUM_P(x))
+     _r = f_boolcast(FIX2INT(x) == 0);
+   else
+     _r = rb_funcall(x, id_equal_p, 1, ZERO);
+   return _r;
+}
+
+inline static VALUE
+f_one_p(VALUE x)
+{
+   VALUE _r;
+   if (FIXNUM_P(x))
+     _r = f_boolcast(FIX2INT(x) == 1);
+   else
+     _r = rb_funcall(x, id_equal_p, 1, ONE);
+   return _r;
+}
+
+inline static VALUE
+f_kind_of_p(VALUE x, VALUE c)
+{
+  return rb_obj_is_kind_of(x, c);
+}
+
+inline static VALUE
+k_numeric_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cNumeric);
+}
+
+inline static VALUE
+k_integer_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cInteger);
+}
+
+inline static VALUE
+k_float_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cFloat);
+}
+
+inline static VALUE
+k_rational_p(VALUE x)
+{
+  return f_kind_of_p(x, rb_cRational);
+}
+
+#ifndef NDEBUG
+#define f_gcd f_gcd_orig
+#endif
+
 inline static long
 i_gcd(long x, long y)
 {
@@ -133,6 +331,21 @@
   /* NOTREACHED */
 }
 
+#ifndef NDEBUG
+#undef f_gcd
+
+inline static VALUE
+f_gcd(VALUE x, VALUE y)
+{
+  VALUE r = f_gcd_orig(x, y);
+  if (!f_zero_p(r)) {
+    assert(f_zero_p(f_mod(x, r)));
+    assert(f_zero_p(f_mod(y, r)));
+  }
+  return r;
+}
+#endif
+
 VALUE
 rb_gcd(VALUE x, VALUE y)
 {
@@ -236,6 +449,27 @@
     return nurat_s_new_internal(klass, num, den);
 }
 
+inline static VALUE
+nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den)
+{
+  switch (FIX2INT(f_cmp(den, ZERO))) {
+  case -1:
+    if (f_negative_p(den)) {
+      num = f_negate(num);
+      den = f_negate(den);
+    }
+    break;
+  case 0:
+    rb_raise(rb_eZeroDivError, "devided by zero");
+    break;
+  }
+
+  if (f_equal_p(den, ONE) && f_unify_p(klass))
+    return num;
+  else
+    return nurat_s_new_internal(klass, num, den);
+}
+
 static VALUE
 nurat_s_canonicalize(int argc, VALUE *argv, VALUE klass)
 {
@@ -311,6 +545,21 @@
   return nurat_s_canonicalize_internal(klass, x, y);
 }
 
+inline static VALUE
+f_rational_new_no_reduce1(VALUE klass, VALUE x)
+{
+  assert(!k_rational_p(x));
+  return nurat_s_canonicalize_internal_no_reduce(klass, x, ONE);
+}
+
+inline static VALUE
+f_rational_new_no_reduce2(VALUE klass, VALUE x, VALUE y)
+{
+  assert(!k_rational_p(x));
+  assert(!k_rational_p(y));
+  return nurat_s_canonicalize_internal_no_reduce(klass, x, y);
+}
+
 static VALUE
 nurat_f_rational(int argc, VALUE *argv, VALUE klass)
 {
@@ -331,27 +580,112 @@
   return dat->den;
 }
 
+#ifndef NDEBUG
+#define f_imul f_imul_orig
+#endif
+
+inline static VALUE
+f_imul(long a, long b)
+{
+  VALUE r;
+  long c;
+
+  if (a == 0 || b == 0)
+    return ZERO;
+  else if (a == 1)
+    return LONG2NUM(b);
+  else if (b == 1)
+    return LONG2NUM(a);
+
+  c = a * b;
+  r = LONG2NUM(c);
+  if (NUM2LONG(r) != c || (c / a) != b)
+    r = rb_big_mul(rb_int2big(a), rb_int2big(b));
+  return r;
+}
+
+#ifndef NDEBUG
+#undef f_imul
+
+inline static VALUE
+f_imul(long x, long y)
+{
+  VALUE r = f_imul_orig(x, y);
+  assert(f_equal_p(r, f_mul(LONG2NUM(x), LONG2NUM(y))));
+  return r;
+}
+#endif
+
+inline static VALUE
+f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
+{
+  VALUE num, den;
+
+  if (FIXNUM_P(anum) && FIXNUM_P(aden) &&
+      FIXNUM_P(bnum) && FIXNUM_P(bden)) {
+    long an = FIX2LONG(anum);
+    long ad = FIX2LONG(aden);
+    long bn = FIX2LONG(bnum);
+    long bd = FIX2LONG(bden);
+    long ig = i_gcd(ad, bd);
+
+    VALUE g = LONG2NUM(ig);
+    VALUE a = f_imul(an, bd / ig);
+    VALUE b = f_imul(bn, ad / ig);
+    VALUE c;
+
+    if (k == '+')
+      c = f_add(a, b);
+    else
+      c = f_sub(a, b);
+
+    b = f_idiv(aden, g);
+    g = f_gcd(c, g);
+    num = f_idiv(c, g);
+    a = f_idiv(bden, g);
+    den = f_mul(a, b);
+  } else {
+    VALUE g = f_gcd(aden, bden);
+    VALUE a = f_mul(anum, f_idiv(bden, g));
+    VALUE b = f_mul(bnum, f_idiv(aden, g));
+    VALUE c;
+
+    if (k == '+')
+      c = f_add(a, b);
+    else
+      c = f_sub(a, b);
+
+    b = f_idiv(aden, g);
+    g = f_gcd(c, g);
+    num = f_idiv(c, g);
+    a = f_idiv(bden, g);
+    den = f_mul(a, b);
+  }
+  return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
+}
+
 static VALUE
 nurat_add(VALUE self, VALUE other)
 {
   switch (TYPE(other)) {
   case T_FIXNUM:
   case T_BIGNUM:
-    return f_add(self, f_rational_new_bang1(CLASS_OF(self), other));
+    {
+      get_dat1(self);
+
+      return f_addsub(self,
+		      dat->num, dat->den,
+		      other, ONE, '+');
+    }
   case T_FLOAT:
     return f_add(f_to_f(self), other);
   case T_RATIONAL:
     {
-      VALUE num1, num2;
-
       get_dat2(self, other);
 
-      num1 = f_mul(adat->num, bdat->den);
-      num2 = f_mul(bdat->num, adat->den);
-
-      return f_rational_new2(CLASS_OF(self),
-			     f_add(num1, num2),
-			     f_mul(adat->den, bdat->den));
+      return f_addsub(self,
+		      adat->num, adat->den,
+		      bdat->num, bdat->den, '+');
     }
   default:
     {
@@ -367,21 +701,22 @@
   switch (TYPE(other)) {
   case T_FIXNUM:
   case T_BIGNUM:
-    return f_sub(self, f_rational_new_bang1(CLASS_OF(self), other));
+    {
+      get_dat1(self);
+
+      return f_addsub(self,
+		      dat->num, dat->den,
+		      other, ONE, '-');
+    }
   case T_FLOAT:
     return f_sub(f_to_f(self), other);
   case T_RATIONAL:
     {
-      VALUE num1, num2;
-
       get_dat2(self, other);
 
-      num1 = f_mul(adat->num, bdat->den);
-      num2 = f_mul(bdat->num, adat->den);
-
-      return f_rational_new2(CLASS_OF(self),
-			     f_sub(num1, num2),
-			     f_mul(adat->den, bdat->den));
+      return f_addsub(self,
+		      adat->num, adat->den,
+		      bdat->num, bdat->den, '-');
     }
   default:
     {
@@ -391,25 +726,66 @@
   }
 }
 
+inline static VALUE
+f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
+{
+  VALUE num, den;
+
+  if (k == '/') {
+    VALUE t;
+
+    if (f_negative_p(bnum)) {
+      anum = f_negate(anum);
+      bnum = f_negate(bnum);
+    }
+    t = bnum;
+    bnum = bden;
+    bden = t;
+  }
+
+  if (FIXNUM_P(anum) && FIXNUM_P(aden) &&
+      FIXNUM_P(bnum) && FIXNUM_P(bden)) {
+    long an = FIX2LONG(anum);
+    long ad = FIX2LONG(aden);
+    long bn = FIX2LONG(bnum);
+    long bd = FIX2LONG(bden);
+    long g1 = i_gcd(an, bd);
+    long g2 = i_gcd(ad, bn);
+
+    num = f_imul(an / g1, bn / g2);
+    den = f_imul(ad / g2, bd / g1);
+  } else {
+    VALUE g1 = f_gcd(anum, bden);
+    VALUE g2 = f_gcd(aden, bnum);
+
+    num = f_mul(f_idiv(anum, g1), f_idiv(bnum, g2));
+    den = f_mul(f_idiv(aden, g2), f_idiv(bden, g1));
+  }
+  return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
+}
+
 static VALUE
 nurat_mul(VALUE self, VALUE other)
 {
   switch (TYPE(other)) {
   case T_FIXNUM:
   case T_BIGNUM:
-    return f_mul(self, f_rational_new_bang1(CLASS_OF(self), other));
+    {
+      get_dat1(self);
+
+      return f_muldiv(self,
+		      dat->num, dat->den,
+		      other, ONE, '*');
+    }
   case T_FLOAT:
     return f_mul(f_to_f(self), other);
   case T_RATIONAL:
     {
-      VALUE num, den;
-
       get_dat2(self, other);
 
-      num = f_mul(adat->num, bdat->num);
-      den = f_mul(adat->den, bdat->den);
-
-      return f_rational_new2(CLASS_OF(self), num, den);
+      return f_muldiv(self,
+		      adat->num, adat->den,
+		      bdat->num, bdat->den, '*');
     }
   default:
     {
@@ -427,19 +803,24 @@
   case T_BIGNUM:
     if (f_zero_p(other))
       rb_raise(rb_eZeroDivError, "devided by zero");
-    return f_div(self, f_rational_new_bang1(CLASS_OF(self), other));
+    {
+      get_dat1(self);
+
+      return f_muldiv(self,
+		      dat->num, dat->den,
+		      other, ONE, '/');
+    }
   case T_FLOAT:
     return f_div(f_to_f(self), other);
   case T_RATIONAL:
+    if (f_zero_p(other))
+      rb_raise(rb_eZeroDivError, "devided by zero");
     {
-      VALUE num, den;
-
       get_dat2(self, other);
 
-      num = f_mul(adat->num, bdat->den);
-      den = f_mul(adat->den, bdat->num);
-
-      return f_rational_new2(CLASS_OF(self), num, den);
+      return f_muldiv(self,
+		      adat->num, adat->den,
+		      bdat->num, bdat->den, '/');
     }
   default:
     {
@@ -513,7 +894,14 @@
   switch (TYPE(other)) {
   case T_FIXNUM:
   case T_BIGNUM:
-    return f_cmp(self, f_rational_new_bang1(CLASS_OF(self), other));
+    {
+      get_dat1(self);
+
+      if (FIXNUM_P(dat->den) && FIX2INT(dat->den) == 1)
+	return f_cmp(dat->num, other);
+      else
+	return f_cmp(self, f_rational_new_bang1(CLASS_OF(self), other));
+    }
   case T_FLOAT:
     return f_cmp(f_to_f(self), other);
   case T_RATIONAL:
@@ -522,8 +910,14 @@
 
       get_dat2(self, other);
 
-      num1 = f_mul(adat->num, bdat->den);
-      num2 = f_mul(bdat->num, adat->den);
+      if (FIXNUM_P(adat->num) && FIXNUM_P(adat->den) &&
+	  FIXNUM_P(bdat->num) && FIXNUM_P(bdat->den)) {
+	num1 = f_imul(FIX2INT(adat->num), FIX2INT(bdat->den));
+	num2 = f_imul(FIX2INT(bdat->num), FIX2INT(adat->den));
+      } else {
+	num1 = f_mul(adat->num, bdat->den);
+	num2 = f_mul(bdat->num, adat->den);
+      }
       return f_cmp(f_sub(num1, num2), ZERO);
     }
   default:
@@ -540,7 +934,18 @@
   switch (TYPE(other)) {
   case T_FIXNUM:
   case T_BIGNUM:
-    return f_equal_p(self, f_rational_new_bang1(CLASS_OF(self), other));
+    {
+      get_dat1(self);
+
+      if (!FIXNUM_P(dat->den))
+	return Qfalse;
+      if (FIX2INT(dat->den) != 1)
+	return Qfalse;
+      if (f_equal_p(dat->num, other))
+	return Qtrue;
+      else
+	return Qfalse;
+    }
   case T_FLOAT:
     return f_equal_p(f_to_f(self), other);
   case T_RATIONAL:
@@ -666,11 +1071,87 @@
   }
 }
 
+#define f_size(x) rb_funcall(x, rb_intern("size"), 0)
+#define f_rshift(x,y) rb_funcall(x, rb_intern(">>"), 1, y)
+
+inline static long
+i_ilog2(VALUE x)
+{
+  long q, r, fx;
+
+  assert(!f_lt_p(x, ONE));
+
+  q = (NUM2LONG(f_size(x)) - sizeof(long)) * 8 + 1;
+
+  if (q > 0)
+    x = f_rshift(x, LONG2NUM(q));
+
+  fx = NUM2LONG(x);
+
+  r = -1;
+  while (fx) {
+    fx >>= 1;
+    r += 1;
+  }
+
+  return q + r;
+}
+
+#include <float.h>
+
 static VALUE
 nurat_to_f(VALUE self)
 {
   get_dat1(self);
-  return f_div(f_to_f(dat->num), dat->den); /* enough? */
+  VALUE num, den;
+  int minus = 0;
+  long nl, dl, ml, ne, de;
+  int e;
+  double f;
+
+  if (f_zero_p(dat->num))
+    return rb_float_new(0.0);
+
+  num = dat->num;
+  den = dat->den;
+
+  if (f_negative_p(num)) {
+    num = f_negate(num);
+    minus = 1;
+  }
+
+  nl = i_ilog2(num);
+  dl = i_ilog2(den);
+  ml = (long)(log(DBL_MAX) / log(2) - 1); /* should be a static */
+
+  ne = 0;
+  if (nl > ml) {
+    ne = nl - ml;
+    num = f_rshift(num, LONG2NUM(ne));
+  }
+
+  de = 0;
+  if (dl > ml) {
+    de = dl - ml;
+    den = f_rshift(den, LONG2NUM(de));
+  }
+
+  e = (int)(ne - de);
+
+  if ((e > DBL_MAX_EXP) || (e < DBL_MIN_EXP)) {
+    rb_warn("%s out of Float range", rb_obj_classname(self));
+    return rb_float_new(e > 0 ? HUGE_VAL : 0.0);
+  }
+
+  f = NUM2DBL(num) / NUM2DBL(den);
+  if (minus)
+    f = -f;
+  f = ldexp(f, e);
+
+  if (isinf(f) || isnan(f))
+    rb_warn("%s out of Float range", rb_obj_classname(self));
+
+  return rb_float_new(f);
 }
 
 static VALUE

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]