mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (rb_big_fdiv): flo.fdiv(NaN) should result NaN.
* numeric.c (num_quo): renamed and moved from bignum.c. [ruby-dev:34582] * bignum.c (rb_big_fdiv): update RDoc description * rational.c (nurat_s_new_m): small refactoring. * bignum.c (rb_big2dbl): no need for forceful warning when converting to float. overflow is a nature of float values. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16308 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f7b3f1c528
commit
fa16110326
6 changed files with 44 additions and 59 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
Wed May 7 13:02:56 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* bignum.c (rb_big_fdiv): flo.fdiv(NaN) should result NaN.
|
||||||
|
|
||||||
|
* numeric.c (num_quo): renamed and moved from bignum.c.
|
||||||
|
[ruby-dev:34582]
|
||||||
|
|
||||||
|
* bignum.c (rb_big_fdiv): update RDoc description
|
||||||
|
|
||||||
|
* rational.c (nurat_s_new_m): small refactoring.
|
||||||
|
|
||||||
|
* bignum.c (rb_big2dbl): no need for forceful warning when
|
||||||
|
converting to float. overflow is a nature of float values.
|
||||||
|
|
||||||
Wed May 7 00:54:25 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Wed May 7 00:54:25 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* ext/zlib/zlib.c (gzreader_gets): may cause infinite loop.
|
* ext/zlib/zlib.c (gzreader_gets): may cause infinite loop.
|
||||||
|
|
15
bignum.c
15
bignum.c
|
@ -1219,7 +1219,7 @@ rb_big2dbl(VALUE x)
|
||||||
double d = big2dbl(x);
|
double d = big2dbl(x);
|
||||||
|
|
||||||
if (isinf(d)) {
|
if (isinf(d)) {
|
||||||
rb_warn("Bignum out of Float range");
|
rb_warning("Bignum out of Float range");
|
||||||
d = HUGE_VAL;
|
d = HUGE_VAL;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
|
@ -1975,23 +1975,16 @@ static VALUE big_shift(VALUE x, int n)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* big.quo(numeric) -> float
|
|
||||||
* big.fdiv(numeric) -> float
|
* big.fdiv(numeric) -> float
|
||||||
*
|
*
|
||||||
* Returns the floating point result of dividing <i>big</i> by
|
* Returns the floating point result of dividing <i>big</i> by
|
||||||
* <i>numeric</i>.
|
* <i>numeric</i>.
|
||||||
*
|
*
|
||||||
* -1234567890987654321.quo(13731) #=> -89910996357705.5
|
* -1234567890987654321.fdiv(13731) #=> -89910996357705.5
|
||||||
* -1234567890987654321.quo(13731.24) #=> -89909424858035.7
|
* -1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
|
||||||
rb_big_quo(VALUE x, VALUE y)
|
|
||||||
{
|
|
||||||
return rb_funcall(rb_rational_raw1(x), '/', 1, rb_Rational1(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_big_fdiv(VALUE x, VALUE y)
|
rb_big_fdiv(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
@ -2021,6 +2014,7 @@ rb_big_fdiv(VALUE x, VALUE y)
|
||||||
return DOUBLE2NUM(ldexp(big2dbl(z), ex - ey));
|
return DOUBLE2NUM(ldexp(big2dbl(z), ex - ey));
|
||||||
}
|
}
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
|
if (isnan(RFLOAT_VALUE(y))) return y;
|
||||||
y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &ey), DBL_MANT_DIG));
|
y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &ey), DBL_MANT_DIG));
|
||||||
ey -= DBL_MANT_DIG;
|
ey -= DBL_MANT_DIG;
|
||||||
goto bignum;
|
goto bignum;
|
||||||
|
@ -2688,7 +2682,6 @@ Init_Bignum(void)
|
||||||
rb_define_method(rb_cBignum, "divmod", rb_big_divmod, 1);
|
rb_define_method(rb_cBignum, "divmod", rb_big_divmod, 1);
|
||||||
rb_define_method(rb_cBignum, "modulo", rb_big_modulo, 1);
|
rb_define_method(rb_cBignum, "modulo", rb_big_modulo, 1);
|
||||||
rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
|
rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
|
||||||
rb_define_method(rb_cBignum, "quo", rb_big_quo, 1);
|
|
||||||
rb_define_method(rb_cBignum, "fdiv", rb_big_fdiv, 1);
|
rb_define_method(rb_cBignum, "fdiv", rb_big_fdiv, 1);
|
||||||
rb_define_method(rb_cBignum, "**", rb_big_pow, 1);
|
rb_define_method(rb_cBignum, "**", rb_big_pow, 1);
|
||||||
rb_define_method(rb_cBignum, "&", rb_big_and, 1);
|
rb_define_method(rb_cBignum, "&", rb_big_and, 1);
|
||||||
|
|
17
numeric.c
17
numeric.c
|
@ -249,15 +249,14 @@ num_uminus(VALUE num)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* num.quo(numeric) => result
|
* num.quo(numeric) => result
|
||||||
* num.fdiv(numeric) => result
|
|
||||||
*
|
*
|
||||||
* Equivalent to <code>Numeric#/</code>, but overridden in subclasses.
|
* Returns most exact division (rational for integers, float for floats).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
num_quo(VALUE x, VALUE y)
|
num_quo(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
return rb_funcall(x, '/', 1, y);
|
return rb_funcall(rb_rational_raw1(x), '/', 1, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2215,23 +2214,16 @@ fixdivmod(long x, long y, long *divp, long *modp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* 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
|
* Returns the floating point result of dividing <i>fix</i> by
|
||||||
* <i>numeric</i>.
|
* <i>numeric</i>.
|
||||||
*
|
*
|
||||||
* 654321.quo(13731) #=> 47.6528293642124
|
* 654321.fdiv(13731) #=> 47.6528293642124
|
||||||
* 654321.quo(13731.24) #=> 47.6519964693647
|
* 654321.fdiv(13731.24) #=> 47.6519964693647
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
|
||||||
fix_quo(VALUE x, VALUE y)
|
|
||||||
{
|
|
||||||
return rb_funcall(rb_rational_raw1(x), '/', 1, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
fix_fdiv(VALUE x, VALUE y)
|
fix_fdiv(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
@ -3225,7 +3217,6 @@ Init_Numeric(void)
|
||||||
rb_define_method(rb_cFixnum, "%", fix_mod, 1);
|
rb_define_method(rb_cFixnum, "%", fix_mod, 1);
|
||||||
rb_define_method(rb_cFixnum, "modulo", 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, "divmod", fix_divmod, 1);
|
||||||
rb_define_method(rb_cFixnum, "quo", fix_quo, 1);
|
|
||||||
rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1);
|
rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1);
|
||||||
rb_define_method(rb_cFixnum, "**", fix_pow, 1);
|
rb_define_method(rb_cFixnum, "**", fix_pow, 1);
|
||||||
|
|
||||||
|
|
40
rational.c
40
rational.c
|
@ -500,10 +500,8 @@ nurat_s_canonicalize(int argc, VALUE *argv, VALUE klass)
|
||||||
{
|
{
|
||||||
VALUE num, den;
|
VALUE num, den;
|
||||||
|
|
||||||
switch (rb_scan_args(argc, argv, "11", &num, &den)) {
|
if (rb_scan_args(argc, argv, "11", &num, &den) == 1) {
|
||||||
case 1:
|
|
||||||
den = ONE;
|
den = ONE;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nurat_int_check(num);
|
nurat_int_check(num);
|
||||||
|
@ -514,22 +512,25 @@ nurat_s_canonicalize(int argc, VALUE *argv, VALUE klass)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
nurat_s_new(int argc, VALUE *argv, VALUE klass)
|
nurat_s_new(VALUE klass, VALUE num, VALUE den)
|
||||||
{
|
{
|
||||||
VALUE num, den;
|
|
||||||
|
|
||||||
switch (rb_scan_args(argc, argv, "11", &num, &den)) {
|
|
||||||
case 1:
|
|
||||||
den = ONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
nurat_int_check(num);
|
nurat_int_check(num);
|
||||||
nurat_int_check(den);
|
nurat_int_check(den);
|
||||||
|
|
||||||
return nurat_s_canonicalize_internal(klass, num, den);
|
return nurat_s_canonicalize_internal(klass, num, den);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
nurat_s_new_m(int argc, VALUE *argv, VALUE klass)
|
||||||
|
{
|
||||||
|
VALUE num, den;
|
||||||
|
|
||||||
|
if (rb_scan_args(argc, argv, "11", &num, &den) == 1) {
|
||||||
|
den = ONE;
|
||||||
|
}
|
||||||
|
return nurat_s_new(klass, num, den);
|
||||||
|
}
|
||||||
|
|
||||||
inline static VALUE
|
inline static VALUE
|
||||||
f_rational_new1(VALUE klass, VALUE x)
|
f_rational_new1(VALUE klass, VALUE x)
|
||||||
{
|
{
|
||||||
|
@ -1425,9 +1426,9 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass)
|
||||||
{
|
{
|
||||||
VALUE a1, a2;
|
VALUE a1, a2;
|
||||||
|
|
||||||
a1 = Qnil;
|
if (rb_scan_args(argc, argv, "02", &a1, &a2) == 1) {
|
||||||
a2 = Qnil;
|
a2 = ONE;
|
||||||
rb_scan_args(argc, argv, "02", &a1, &a2);
|
}
|
||||||
|
|
||||||
switch (TYPE(a1)) {
|
switch (TYPE(a1)) {
|
||||||
case T_COMPLEX:
|
case T_COMPLEX:
|
||||||
|
@ -1486,12 +1487,7 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass)
|
||||||
return f_div(a1, a2);
|
return f_div(a1, a2);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
return nurat_s_new(klass, a1, a2);
|
||||||
VALUE argv2[2];
|
|
||||||
argv2[0] = a1;
|
|
||||||
argv2[1] = a2;
|
|
||||||
return nurat_s_new(argc, argv2, klass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -1533,7 +1529,7 @@ Init_Rational(void)
|
||||||
rb_funcall(rb_cRational, rb_intern("private_class_method"), 1,
|
rb_funcall(rb_cRational, rb_intern("private_class_method"), 1,
|
||||||
ID2SYM(rb_intern("new!")));
|
ID2SYM(rb_intern("new!")));
|
||||||
|
|
||||||
rb_define_singleton_method(rb_cRational, "new", nurat_s_new, -1);
|
rb_define_singleton_method(rb_cRational, "new", nurat_s_new_m, -1);
|
||||||
rb_funcall(rb_cRational, rb_intern("private_class_method"), 1,
|
rb_funcall(rb_cRational, rb_intern("private_class_method"), 1,
|
||||||
ID2SYM(rb_intern("new")));
|
ID2SYM(rb_intern("new")));
|
||||||
|
|
||||||
|
|
|
@ -263,14 +263,14 @@ class TestBignum < Test::Unit::TestCase
|
||||||
assert_equal(T32.to_f, T32.quo(1.0))
|
assert_equal(T32.to_f, T32.quo(1.0))
|
||||||
assert_equal(T32.to_f, T32.quo(T_ONE))
|
assert_equal(T32.to_f, T32.quo(T_ONE))
|
||||||
|
|
||||||
assert_raise(ArgumentError) { T32.quo("foo") }
|
assert_raise(TypeError) { T32.quo("foo") }
|
||||||
|
|
||||||
assert_equal(1024**1024, (1024**1024).quo(1))
|
assert_equal(1024**1024, (1024**1024).quo(1))
|
||||||
assert_equal(1024**1024, (1024**1024).quo(1.0))
|
assert_equal(1024**1024, (1024**1024).quo(1.0))
|
||||||
assert_equal(1024**1024*2, (1024**1024*2).quo(1))
|
assert_equal(1024**1024*2, (1024**1024*2).quo(1))
|
||||||
inf = 1 / 0.0; nan = inf / inf
|
inf = 1 / 0.0; nan = inf / inf
|
||||||
|
|
||||||
assert_raise(FloatDomainError) { (1024**1024*2).quo(nan) }
|
assert((1024**1024*2).quo(nan).nan?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pow
|
def test_pow
|
||||||
|
|
|
@ -51,16 +51,7 @@ class TestNumeric < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_quo
|
def test_quo
|
||||||
DummyNumeric.class_eval do
|
assert_raise(ArgumentError) {DummyNumeric.new.quo(1)}
|
||||||
def /(x); :div; end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal(:div, DummyNumeric.new.quo(0))
|
|
||||||
|
|
||||||
ensure
|
|
||||||
DummyNumeric.class_eval do
|
|
||||||
remove_method :/
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_divmod
|
def test_divmod
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue