зеркало из https://github.com/github/ruby.git
* numeric.c (num_rdiv): should always return rational number.
* rational.c (nurat_add, nurat_sub, nurat_mul, nurat_fdiv, nurat_cmp): use rb_num_coerce_bin(). * rational.c (nurat_division): does / and rdiv. * .gdbinit (rp): no longer use rb_p(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
f67f196b1d
Коммит
c3d2e4d381
4
.gdbinit
4
.gdbinit
|
@ -145,11 +145,11 @@ define rp
|
|||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_RATIONAL
|
||||
printf "T_RATIONAL: "
|
||||
rb_p $arg0
|
||||
print (struct RRational *)$arg0
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_COMPLEX
|
||||
printf "T_COMPLEX: "
|
||||
rb_p $arg0
|
||||
print (struct RComplex *)$arg0
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_FILE
|
||||
printf "T_FILE: "
|
||||
|
|
|
@ -2,6 +2,15 @@ Wed Apr 2 22:29:35 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
|||
|
||||
* rational.c (nurat_int_check): function for DRY integer check.
|
||||
|
||||
* numeric.c (num_rdiv): should always return rational number.
|
||||
|
||||
* rational.c (nurat_add, nurat_sub, nurat_mul, nurat_fdiv,
|
||||
nurat_cmp): use rb_num_coerce_bin().
|
||||
|
||||
* rational.c (nurat_division): does / and rdiv.
|
||||
|
||||
* .gdbinit (rp): no longer use rb_p().
|
||||
|
||||
Wed Apr 2 06:52:31 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* .gdbinit (rp): supports rational and complex numbers. it's
|
||||
|
|
69
numeric.c
69
numeric.c
|
@ -248,18 +248,46 @@ num_uminus(VALUE num)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* num.quo(numeric) => result
|
||||
* num.fdiv(numeric) => result
|
||||
*
|
||||
* Equivalent to <code>Numeric#/</code>, but overridden in subclasses.
|
||||
* Performs floating point division.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
num_quo(VALUE x, VALUE y)
|
||||
num_fdiv(VALUE x, VALUE y)
|
||||
{
|
||||
return rb_funcall(x, '/', 1, rb_Rational1(y));
|
||||
return rb_funcall(rb_Float(x), '/', 1, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-method: quo
|
||||
*
|
||||
* call-seq:
|
||||
* num.quo(numeric) => result
|
||||
*
|
||||
* Suppose to return most accurate division result, which
|
||||
* by default in ratinal number for 1.9.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Document-method: rdiv
|
||||
*
|
||||
* call-seq:
|
||||
* num.rdiv(numeric) => result
|
||||
*
|
||||
* Performs rational number division.
|
||||
*
|
||||
* 654321.rdiv(13731) #=> Rational(218107, 4577)
|
||||
* 654321.rdiv(13731.5) #=> Rational(1308642, 27463)
|
||||
*
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
num_rdiv(VALUE x, VALUE y)
|
||||
{
|
||||
return rb_funcall(rb_Rational1(x), rb_intern("rdiv"), 1, y);
|
||||
}
|
||||
|
||||
static VALUE num_floor(VALUE num);
|
||||
|
||||
|
@ -647,17 +675,11 @@ flo_div(VALUE x, VALUE y)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
flo_quo(VALUE x, VALUE y)
|
||||
flo_fdiv(VALUE x, VALUE y)
|
||||
{
|
||||
return rb_funcall(x, '/', 1, y);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
flo_rdiv(VALUE x, VALUE y)
|
||||
{
|
||||
return rb_funcall(rb_Rational1(x), '/', 1, y);
|
||||
}
|
||||
|
||||
static void
|
||||
flodivmod(double x, double y, double *divp, double *modp)
|
||||
{
|
||||
|
@ -2221,23 +2243,16 @@ fixdivmod(long x, long y, long *divp, long *modp)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* fix.quo(numeric) => float
|
||||
* fix.fdiv(numeric) => float
|
||||
* fix.fdiv(numeric) => float
|
||||
*
|
||||
* Returns the floating point result of dividing <i>fix</i> by
|
||||
* <i>numeric</i>.
|
||||
*
|
||||
* 654321.quo(13731) #=> 47.6528293642124
|
||||
* 654321.quo(13731.24) #=> 47.6519964693647
|
||||
* 654321.rdiv(13731) #=> Rational(218107, 4577)
|
||||
* 654321.rdiv(13731.24) #=> Rational(1308642, 27463)
|
||||
*
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
fix_quo(VALUE x, VALUE y)
|
||||
{
|
||||
return rb_funcall(rb_rational_raw1(x), '/', 1, y);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
fix_fdiv(VALUE x, VALUE y)
|
||||
{
|
||||
|
@ -3162,9 +3177,9 @@ Init_Numeric(void)
|
|||
rb_define_method(rb_cNumeric, "-@", num_uminus, 0);
|
||||
rb_define_method(rb_cNumeric, "<=>", num_cmp, 1);
|
||||
rb_define_method(rb_cNumeric, "eql?", num_eql, 1);
|
||||
rb_define_method(rb_cNumeric, "quo", num_quo, 1);
|
||||
rb_define_method(rb_cNumeric, "rdiv", num_quo, 1);
|
||||
rb_define_method(rb_cNumeric, "fdiv", num_quo, 1);
|
||||
rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1);
|
||||
rb_define_method(rb_cNumeric, "quo", num_rdiv, 1);
|
||||
rb_define_method(rb_cNumeric, "rdiv", num_rdiv, 1);
|
||||
rb_define_method(rb_cNumeric, "div", num_div, 1);
|
||||
rb_define_method(rb_cNumeric, "divmod", num_divmod, 1);
|
||||
rb_define_method(rb_cNumeric, "modulo", num_modulo, 1);
|
||||
|
@ -3230,8 +3245,6 @@ Init_Numeric(void)
|
|||
rb_define_method(rb_cFixnum, "%", fix_mod, 1);
|
||||
rb_define_method(rb_cFixnum, "modulo", fix_mod, 1);
|
||||
rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);
|
||||
rb_define_method(rb_cFixnum, "quo", fix_quo, 1);
|
||||
rb_define_method(rb_cFixnum, "rdiv", fix_quo, 1);
|
||||
rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1);
|
||||
rb_define_method(rb_cFixnum, "**", fix_pow, 1);
|
||||
|
||||
|
@ -3287,9 +3300,7 @@ Init_Numeric(void)
|
|||
rb_define_method(rb_cFloat, "-", flo_minus, 1);
|
||||
rb_define_method(rb_cFloat, "*", flo_mul, 1);
|
||||
rb_define_method(rb_cFloat, "/", flo_div, 1);
|
||||
rb_define_method(rb_cFloat, "quo", flo_quo, 1);
|
||||
rb_define_method(rb_cFloat, "rdiv", flo_rdiv, 1);
|
||||
rb_define_method(rb_cFloat, "fdiv", flo_quo, 1);
|
||||
rb_define_method(rb_cFloat, "fdiv", flo_fdiv, 1);
|
||||
rb_define_method(rb_cFloat, "%", flo_mod, 1);
|
||||
rb_define_method(rb_cFloat, "modulo", flo_mod, 1);
|
||||
rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
|
||||
|
|
64
rational.c
64
rational.c
|
@ -22,7 +22,7 @@
|
|||
|
||||
VALUE rb_cRational;
|
||||
|
||||
static ID id_Unify, id_abs, id_cmp, id_coerce, id_convert, id_equal_p,
|
||||
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;
|
||||
|
||||
|
@ -175,8 +175,6 @@ fun1(to_i)
|
|||
fun1(to_s)
|
||||
fun1(truncate)
|
||||
|
||||
fun2(coerce)
|
||||
|
||||
inline static VALUE
|
||||
f_equal_p(VALUE x, VALUE y)
|
||||
{
|
||||
|
@ -681,10 +679,7 @@ nurat_add(VALUE self, VALUE other)
|
|||
bdat->num, bdat->den, '+');
|
||||
}
|
||||
default:
|
||||
{
|
||||
VALUE a = f_coerce(other, self);
|
||||
return f_add(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, '+');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,10 +707,7 @@ nurat_sub(VALUE self, VALUE other)
|
|||
bdat->num, bdat->den, '-');
|
||||
}
|
||||
default:
|
||||
{
|
||||
VALUE a = f_coerce(other, self);
|
||||
return f_sub(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, '-');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,16 +773,17 @@ nurat_mul(VALUE self, VALUE other)
|
|||
bdat->num, bdat->den, '*');
|
||||
}
|
||||
default:
|
||||
{
|
||||
VALUE a = f_coerce(other, self);
|
||||
return f_mul(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, '*');
|
||||
}
|
||||
}
|
||||
|
||||
#define id_to_r rb_intern("to_r")
|
||||
#define f_to_r(x) rb_funcall(x, id_to_r, 0)
|
||||
|
||||
static VALUE
|
||||
nurat_div(VALUE self, VALUE other)
|
||||
nurat_division(VALUE self, VALUE other, int rdiv)
|
||||
{
|
||||
again:
|
||||
switch (TYPE(other)) {
|
||||
case T_FIXNUM:
|
||||
case T_BIGNUM:
|
||||
|
@ -804,7 +797,11 @@ nurat_div(VALUE self, VALUE other)
|
|||
other, ONE, '/');
|
||||
}
|
||||
case T_FLOAT:
|
||||
return f_div(f_to_f(self), other);
|
||||
if (rdiv) {
|
||||
other = f_to_r(other);
|
||||
goto again;
|
||||
}
|
||||
return rb_funcall(f_to_f(self), '/', 1, other);
|
||||
case T_RATIONAL:
|
||||
if (f_zero_p(other))
|
||||
rb_raise(rb_eZeroDivError, "devided by zero");
|
||||
|
@ -816,13 +813,22 @@ nurat_div(VALUE self, VALUE other)
|
|||
bdat->num, bdat->den, '/');
|
||||
}
|
||||
default:
|
||||
{
|
||||
VALUE a = f_coerce(other, self);
|
||||
return f_div(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, '/');
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
nurat_div(VALUE self, VALUE other)
|
||||
{
|
||||
return nurat_division(self, other, Qfalse);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
nurat_rdiv(VALUE self, VALUE other)
|
||||
{
|
||||
return nurat_division(self, other, Qtrue);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
nurat_fdiv(VALUE self, VALUE other)
|
||||
{
|
||||
|
@ -874,10 +880,7 @@ nurat_expt(VALUE self, VALUE other)
|
|||
case T_RATIONAL:
|
||||
return f_expt(f_to_f(self), other);
|
||||
default:
|
||||
{
|
||||
VALUE a = f_coerce(other, self);
|
||||
return f_expt(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, rb_intern("**"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -914,10 +917,7 @@ nurat_cmp(VALUE self, VALUE other)
|
|||
return f_cmp(f_sub(num1, num2), ZERO);
|
||||
}
|
||||
default:
|
||||
{
|
||||
VALUE a = f_coerce(other, self);
|
||||
return f_cmp(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, rb_intern("<=>"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1423,9 +1423,6 @@ string_to_r(VALUE self)
|
|||
return rb_rational_new1(INT2FIX(0));
|
||||
}
|
||||
|
||||
#define id_to_r rb_intern("to_r")
|
||||
#define f_to_r(x) rb_funcall(x, id_to_r, 0)
|
||||
|
||||
static VALUE
|
||||
nurat_s_convert(int argc, VALUE *argv, VALUE klass)
|
||||
{
|
||||
|
@ -1514,7 +1511,6 @@ Init_Rational(void)
|
|||
id_Unify = rb_intern("Unify");
|
||||
id_abs = rb_intern("abs");
|
||||
id_cmp = rb_intern("<=>");
|
||||
id_coerce = rb_intern("coerce");
|
||||
id_convert = rb_intern("convert");
|
||||
id_equal_p = rb_intern("==");
|
||||
id_expt = rb_intern("**");
|
||||
|
@ -1553,6 +1549,8 @@ Init_Rational(void)
|
|||
rb_define_method(rb_cRational, "-", nurat_sub, 1);
|
||||
rb_define_method(rb_cRational, "*", nurat_mul, 1);
|
||||
rb_define_method(rb_cRational, "/", nurat_div, 1);
|
||||
rb_define_method(rb_cRational, "quo", nurat_rdiv, 1);
|
||||
rb_define_method(rb_cRational, "rdiv", nurat_rdiv, 1);
|
||||
rb_define_method(rb_cRational, "fdiv", nurat_fdiv, 1);
|
||||
rb_define_method(rb_cRational, "**", nurat_expt, 1);
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ class TestBignum < Test::Unit::TestCase
|
|||
assert_equal(T32.to_f, T32.quo(1.0))
|
||||
assert_equal(T32.to_f, T32.quo(T_ONE))
|
||||
|
||||
assert_raise(TypeError) { T32.quo("foo") }
|
||||
assert_raise(ArgumentError) { T32.quo("foo") }
|
||||
|
||||
assert_equal(1024**1024, (1024**1024).quo(1))
|
||||
assert_equal(1024**1024, (1024**1024).quo(1.0))
|
||||
|
|
|
@ -51,16 +51,7 @@ class TestNumeric < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_quo
|
||||
DummyNumeric.class_eval do
|
||||
def /(x); :div; end
|
||||
end
|
||||
|
||||
assert_equal(:div, DummyNumeric.new.quo(0))
|
||||
|
||||
ensure
|
||||
DummyNumeric.class_eval do
|
||||
remove_method :/
|
||||
end
|
||||
assert_raise(ArgumentError) {DummyNumeric.new.quo(0)}
|
||||
end
|
||||
|
||||
def test_divmod
|
||||
|
|
|
@ -943,7 +943,7 @@ class Rational_Test < Test::Unit::TestCase
|
|||
|
||||
assert_equal(Rational(1,2), 1.quo(2))
|
||||
assert_equal(Rational(5000000000), 10000000000.quo(2))
|
||||
assert_equal(0.5, 1.0.quo(2))
|
||||
assert_equal(Rational(1,2), 1.0.quo(2))
|
||||
assert_equal(Rational(1,4), Rational(1,2).quo(2))
|
||||
|
||||
assert_equal(Rational(1,2), 1.rdiv(2))
|
||||
|
|
Загрузка…
Ссылка в новой задаче