From 5ac09d7627e6934a53e1f39b59d1e67a30a2fd72 Mon Sep 17 00:00:00 2001 From: tadf Date: Sat, 13 Sep 2008 01:55:56 +0000 Subject: [PATCH] * complex.c: refined. * rational.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19319 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 +++ complex.c | 67 ++++++++++++--------------- rational.c | 94 +++++++++++++++++++++----------------- test/ruby/test_rational.rb | 2 +- 4 files changed, 90 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6555a67a0..787f764c54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sat Sep 13 10:53:13 2008 Tadayoshi Funaba + + * complex.c: refined. + + * rational.c: ditto. + Sat Sep 13 03:44:52 2008 Tanaka Akira * transcode.c (rb_econv_prepare_opts): raise ArgumentError if diff --git a/complex.c b/complex.c index 98541ba607..4d7dc2901c 100644 --- a/complex.c +++ b/complex.c @@ -22,10 +22,10 @@ VALUE rb_cComplex; static ID id_Unify, id_abs, id_abs2, id_arg, id_cmp, id_conjugate, - id_convert, id_denominator, id_divmod, id_equal_p, id_exact_p, id_expt, - id_floor, id_format, id_idiv, id_inspect, id_negate, id_new, id_new_bang, - id_numerator, id_polar, id_quo, id_scalar_p, id_to_f, id_to_i, id_to_r, - id_to_s, id_truncate; + id_convert, id_denominator, id_divmod, id_equal_p, id_exact_p, id_expt, + id_floor, id_format, id_idiv, id_inspect, id_negate, id_new, id_new_bang, + id_numerator, id_polar, id_quo, id_scalar_p, id_to_f, id_to_i, id_to_r, + id_to_s, id_truncate; #define f_boolcast(x) ((x) ? Qtrue : Qfalse) @@ -67,14 +67,10 @@ m_##n(VALUE x, VALUE y)\ inline static VALUE f_add(VALUE x, VALUE y) { - if (FIXNUM_P(y)) { - if (FIX2LONG(y) == 0) - return x; - } - else if (FIXNUM_P(x)) { - if (FIX2LONG(x) == 0) - return y; - } + if (FIXNUM_P(y) && FIX2LONG(y) == 0) + return x; + else if (FIXNUM_P(x) && FIX2LONG(x) == 0) + return y; return rb_funcall(x, '+', 1, y); } @@ -122,25 +118,21 @@ inline static VALUE f_mul(VALUE x, VALUE y) { if (FIXNUM_P(y)) { - long _iy = FIX2LONG(y); - if (_iy == 0) { - if (TYPE(x) == T_FLOAT) - return rb_float_new(0.0); - else + long iy = FIX2LONG(y); + if (iy == 0) { + if (FIXNUM_P(x) || TYPE(x) == T_BIGNUM) return ZERO; } - else if (_iy == 1) + else if (iy == 1) return x; } else if (FIXNUM_P(x)) { - long _ix = FIX2LONG(x); - if (_ix == 0) { - if (TYPE(y) == T_FLOAT) - return rb_float_new(0.0); - else + long ix = FIX2LONG(x); + if (ix == 0) { + if (FIXNUM_P(y) || TYPE(y) == T_BIGNUM) return ZERO; } - else if (_ix == 1) + else if (ix == 1) return y; } return rb_funcall(x, '*', 1, y); @@ -149,9 +141,8 @@ f_mul(VALUE x, VALUE y) inline static VALUE f_sub(VALUE x, VALUE y) { - if (FIXNUM_P(y)) - if (FIX2LONG(y) == 0) - return x; + if (FIXNUM_P(y) && FIX2LONG(y) == 0) + return x; return rb_funcall(x, '-', 1, y); } @@ -779,19 +770,21 @@ nucomp_conjugate(VALUE self) return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->image)); } +#if 0 static VALUE -nucomp_real_p(VALUE self) +nucomp_true(VALUE self) +{ + return Qtrue; +} +#endif + +static VALUE +nucomp_false(VALUE self) { return Qfalse; } #if 0 -static VALUE -nucomp_complex_p(VALUE self) -{ - return Qtrue; -} - static VALUE nucomp_exact_p(VALUE self) { @@ -1427,12 +1420,12 @@ Init_Complex(void) #endif #if 0 - rb_define_method(rb_cComplex, "real?", nucomp_real_p, 0); - rb_define_method(rb_cComplex, "complex?", nucomp_complex_p, 0); + rb_define_method(rb_cComplex, "real?", nucomp_false, 0); + rb_define_method(rb_cComplex, "complex?", nucomp_true, 0); rb_define_method(rb_cComplex, "exact?", nucomp_exact_p, 0); rb_define_method(rb_cComplex, "inexact?", nucomp_inexact_p, 0); #endif - rb_define_method(rb_cComplex, "scalar?", nucomp_real_p, 0); + rb_define_method(rb_cComplex, "scalar?", nucomp_false, 0); rb_define_method(rb_cComplex, "numerator", nucomp_numerator, 0); rb_define_method(rb_cComplex, "denominator", nucomp_denominator, 0); diff --git a/rational.c b/rational.c index f44e52c247..7274ace1ff 100644 --- a/rational.c +++ b/rational.c @@ -9,13 +9,13 @@ #include #include -#define NDEBUG -#include - #ifdef HAVE_IEEEFP_H #include #endif +#define NDEBUG +#include + #ifndef RATIONAL_NAME #define RATIONAL_NAME "Rational" #endif @@ -27,8 +27,8 @@ VALUE rb_cRational; static ID id_Unify, id_abs, id_cmp, id_convert, id_equal_p, id_expt, - 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; + id_floor, id_format, id_idiv, id_inspect, id_integer_p, id_negate, + id_new, id_new_bang, id_to_f, id_to_i, id_to_s, id_truncate; #define f_boolcast(x) ((x) ? Qtrue : Qfalse) @@ -56,14 +56,10 @@ f_##n(VALUE x, VALUE y)\ inline static VALUE f_add(VALUE x, VALUE y) { - if (FIXNUM_P(y)) { - if (FIX2LONG(y) == 0) - return x; - } - else if (FIXNUM_P(x)) { - if (FIX2LONG(x) == 0) - return y; - } + if (FIXNUM_P(y) && FIX2LONG(y) == 0) + return x; + else if (FIXNUM_P(x) && FIX2LONG(x) == 0) + return y; return rb_funcall(x, '+', 1, y); } @@ -111,25 +107,21 @@ inline static VALUE f_mul(VALUE x, VALUE y) { if (FIXNUM_P(y)) { - long _iy = FIX2LONG(y); - if (_iy == 0) { - if (TYPE(x) == T_FLOAT) - return rb_float_new(0.0); - else + long iy = FIX2LONG(y); + if (iy == 0) { + if (FIXNUM_P(x) || TYPE(x) == T_BIGNUM) return ZERO; } - else if (_iy == 1) + else if (iy == 1) return x; } else if (FIXNUM_P(x)) { - long _ix = FIX2LONG(x); - if (_ix == 0) { - if (TYPE(y) == T_FLOAT) - return rb_float_new(0.0); - else + long ix = FIX2LONG(x); + if (ix == 0) { + if (FIXNUM_P(y) || TYPE(y) == T_BIGNUM) return ZERO; } - else if (_ix == 1) + else if (ix == 1) return y; } return rb_funcall(x, '*', 1, y); @@ -138,9 +130,8 @@ f_mul(VALUE x, VALUE y) inline static VALUE f_sub(VALUE x, VALUE y) { - if (FIXNUM_P(y)) - if (FIX2LONG(y) == 0) - return x; + if (FIXNUM_P(y) && FIX2LONG(y) == 0) + return x; return rb_funcall(x, '-', 1, y); } @@ -149,6 +140,7 @@ binop(xor, '^') fun1(abs) fun1(floor) fun1(inspect) +fun1(integer_p) fun1(negate) fun1(to_f) fun1(to_i) @@ -385,10 +377,20 @@ nurat_int_check(VALUE num) case T_BIGNUM: break; default: - rb_raise(rb_eArgError, "not an integer"); + if (!k_numeric_p(num) || !f_integer_p(num)) + rb_raise(rb_eArgError, "not an integer"); } } +inline static VALUE +nurat_int_value(VALUE num) +{ + nurat_int_check(num); + if (!k_integer_p(num)) + num = f_to_i(num); + return num; +} + inline static VALUE nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den) { @@ -426,7 +428,7 @@ nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den) break; } - if (f_equal_p(den, ONE) && f_unify_p(klass)) + if (f_one_p(den) && f_unify_p(klass)) return num; return nurat_s_new_internal(klass, num, den); } @@ -437,13 +439,17 @@ nurat_s_canonicalize(int argc, VALUE *argv, VALUE klass) { VALUE num, den; - if (rb_scan_args(argc, argv, "11", &num, &den) == 1) { + switch (rb_scan_args(argc, argv, "11", &num, &den)) { + case 1: + num = nurat_int_value(num); den = ONE; + break; + default: + num = nurat_int_value(num); + den = nurat_int_value(den); + break; } - nurat_int_check(num); - nurat_int_check(den); - return nurat_s_canonicalize_internal(klass, num, den); } #endif @@ -453,11 +459,16 @@ nurat_s_new(int argc, VALUE *argv, VALUE klass) { VALUE num, den; - if (rb_scan_args(argc, argv, "11", &num, &den) == 1) + switch (rb_scan_args(argc, argv, "11", &num, &den)) { + case 1: + num = nurat_int_value(num); den = ONE; - - nurat_int_check(num); - nurat_int_check(den); + break; + default: + num = nurat_int_value(num); + den = nurat_int_value(den); + break; + } return nurat_s_canonicalize_internal(klass, num, den); } @@ -1135,21 +1146,21 @@ nurat_marshal_load(VALUE self, VALUE a) VALUE rb_gcd(VALUE self, VALUE other) { - nurat_int_check(other); + other = nurat_int_value(other); return f_gcd(self, other); } VALUE rb_lcm(VALUE self, VALUE other) { - nurat_int_check(other); + other = nurat_int_value(other); return f_lcm(self, other); } VALUE rb_gcdlcm(VALUE self, VALUE other) { - nurat_int_check(other); + other = nurat_int_value(other); return rb_assoc_new(f_gcd(self, other), f_lcm(self, other)); } @@ -1477,6 +1488,7 @@ Init_Rational(void) id_format = rb_intern("format"); id_idiv = rb_intern("div"); id_inspect = rb_intern("inspect"); + id_integer_p = rb_intern("integer?"); id_negate = rb_intern("-@"); id_new = rb_intern("new"); id_new_bang = rb_intern("new!"); diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb index 71763242df..1d280e4361 100644 --- a/test/ruby/test_rational.rb +++ b/test/ruby/test_rational.rb @@ -603,7 +603,7 @@ class Rational_Test < Test::Unit::TestCase assert_equal(Rational(3,4), c.quo(c2)) assert_equal(Rational(1,4), c.quo(2)) - assert_equal(Rational(0.25), c.quo(2.0)) + assert_equal(0.25, c.quo(2.0)) end def test_fdiv