mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Add Float::INFINITY and Float::NAN.
* numeric.c (Init_Numeric): Add Float::INFINITY and Float::NAN. [ruby-dev:1657] [ruby-dev:4760] [ruby-list:7023] [ruby-list:46690] [ruby-core:26632] [ruby-talk:41352] [ruby-talk:203333] * include/ruby/defines.h (INFINITY): defined. * include/ruby/defines.h (NAN): defined. * include/ruby/util.h (ruby_div0): removed. * numeric.c (fix_pow): use INFINITY and NAN instead of ruby_div0(1.0). * marshal.c (r_object0): ditto. * bignum.c (big_fdiv): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
92ab16fac6
commit
7ed0640ffb
7 changed files with 67 additions and 27 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
Tue Dec 29 16:03:33 2009 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* numeric.c (Init_Numeric): Add Float::INFINITY and Float::NAN.
|
||||
[ruby-dev:1657] [ruby-dev:4760] [ruby-list:7023]
|
||||
[ruby-list:46690]
|
||||
[ruby-core:26632] [ruby-talk:41352] [ruby-talk:203333]
|
||||
|
||||
* include/ruby/defines.h (INFINITY): defined.
|
||||
|
||||
* include/ruby/defines.h (NAN): defined.
|
||||
|
||||
* include/ruby/util.h (ruby_div0): removed.
|
||||
|
||||
* numeric.c (fix_pow): use INFINITY and NAN
|
||||
instead of ruby_div0(1.0).
|
||||
|
||||
* marshal.c (r_object0): ditto.
|
||||
|
||||
* bignum.c (big_fdiv): ditto.
|
||||
|
||||
Tue Dec 29 10:36:23 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* lib/rexml/parsers/baseparser.rb (REXML::Parsers::BaseParser::STANDALONE):
|
||||
|
|
2
bignum.c
2
bignum.c
|
@ -2485,7 +2485,7 @@ big_fdiv(VALUE x, VALUE y)
|
|||
#if SIZEOF_LONG > SIZEOF_INT
|
||||
{
|
||||
/* Visual C++ can't be here */
|
||||
if (l > INT_MAX) return DBL2NUM(ruby_div0(1.0));
|
||||
if (l > INT_MAX) return DBL2NUM(INFINITY);
|
||||
if (l < INT_MIN) return DBL2NUM(0.0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -99,6 +99,20 @@ void xfree(void*);
|
|||
# define BDIGIT_DBL_SIGNED long
|
||||
#endif
|
||||
|
||||
#ifdef INFINITY
|
||||
# define HAVE_INFINITY
|
||||
#else
|
||||
extern const unsigned char rb_infinity[];
|
||||
# define INFINITY (*(double *)rb_infinity)
|
||||
#endif
|
||||
|
||||
#ifdef NAN
|
||||
# define HAVE_NAN
|
||||
#else
|
||||
extern const unsigned char rb_nan[];
|
||||
# define NAN (*(double *)rb_nan)
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#undef _WIN32
|
||||
#endif
|
||||
|
|
|
@ -74,12 +74,6 @@ double ruby_strtod(const char *, char **);
|
|||
#pragma warning(push)
|
||||
#pragma warning(disable:4723)
|
||||
#endif
|
||||
static inline double
|
||||
ruby_div0(double x)
|
||||
{
|
||||
double t = 0.0;
|
||||
return x / t;
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1300
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
|
|
@ -1322,8 +1322,6 @@ obj_alloc_by_path(VALUE path, struct load_arg *arg)
|
|||
return rb_obj_alloc(klass);
|
||||
}
|
||||
|
||||
#define div0(x) ruby_div0(x)
|
||||
|
||||
static int
|
||||
has_encoding(struct load_arg *arg)
|
||||
{
|
||||
|
@ -1449,13 +1447,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
|
|||
const char *ptr = RSTRING_PTR(str);
|
||||
|
||||
if (strcmp(ptr, "nan") == 0) {
|
||||
d = div0(0.0);
|
||||
d = NAN;
|
||||
}
|
||||
else if (strcmp(ptr, "inf") == 0) {
|
||||
d = div0(+1.0);
|
||||
d = INFINITY;
|
||||
}
|
||||
else if (strcmp(ptr, "-inf") == 0) {
|
||||
d = div0(-1.0);
|
||||
d = -INFINITY;
|
||||
}
|
||||
else {
|
||||
char *e;
|
||||
|
|
22
numeric.c
22
numeric.c
|
@ -63,6 +63,20 @@
|
|||
#define DBL_EPSILON 2.2204460492503131e-16
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INFINITY
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
const unsigned char rb_infinity[] = "\x00\x00\x00\x00\x00\x00\xf0\x7f";
|
||||
#else
|
||||
const unsigned char rb_infinity[] = "\x7f\xf0\x00\x00\x00\x00\x00\x00";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NAN
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
const unsigned char rb_nan[] = "\x00\x00\x00\x00\x00\x00\xf8\x7f";
|
||||
#else
|
||||
const unsigned char rb_nan[] = "\x7f\xf8\x00\x00\x00\x00\x00\x00";
|
||||
#endif
|
||||
|
||||
extern double round(double);
|
||||
|
||||
#ifndef HAVE_ROUND
|
||||
|
@ -2467,8 +2481,6 @@ int_pow(long x, unsigned long y)
|
|||
return LONG2NUM(z);
|
||||
}
|
||||
|
||||
#define infinite_value() ruby_div0(1.0)
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* fix ** numeric -> numeric_result
|
||||
|
@ -2496,7 +2508,7 @@ fix_pow(VALUE x, VALUE y)
|
|||
if (b == 1) return x;
|
||||
if (a == 0) {
|
||||
if (b > 0) return INT2FIX(0);
|
||||
return DBL2NUM(infinite_value());
|
||||
return DBL2NUM(INFINITY);
|
||||
}
|
||||
if (a == 1) return INT2FIX(1);
|
||||
if (a == -1) {
|
||||
|
@ -2524,7 +2536,7 @@ fix_pow(VALUE x, VALUE y)
|
|||
case T_FLOAT:
|
||||
if (RFLOAT_VALUE(y) == 0.0) return DBL2NUM(1.0);
|
||||
if (a == 0) {
|
||||
return DBL2NUM(RFLOAT_VALUE(y) < 0 ? infinite_value() : 0.0);
|
||||
return DBL2NUM(RFLOAT_VALUE(y) < 0 ? INFINITY : 0.0);
|
||||
}
|
||||
if (a == 1) return DBL2NUM(1.0);
|
||||
{
|
||||
|
@ -3305,6 +3317,8 @@ Init_Numeric(void)
|
|||
rb_define_const(rb_cFloat, "MIN", DBL2NUM(DBL_MIN));
|
||||
rb_define_const(rb_cFloat, "MAX", DBL2NUM(DBL_MAX));
|
||||
rb_define_const(rb_cFloat, "EPSILON", DBL2NUM(DBL_EPSILON));
|
||||
rb_define_const(rb_cFloat, "INFINITY", DBL2NUM(INFINITY));
|
||||
rb_define_const(rb_cFloat, "NAN", DBL2NUM(NAN));
|
||||
|
||||
rb_define_method(rb_cFloat, "to_s", flo_to_s, 0);
|
||||
rb_define_method(rb_cFloat, "coerce", flo_coerce, 1);
|
||||
|
|
|
@ -24,7 +24,7 @@ class TestFloat < Test::Unit::TestCase
|
|||
assert_equal(false, (x >= y))
|
||||
end
|
||||
def test_nan
|
||||
nan = 0.0/0
|
||||
nan = Float::NAN
|
||||
nan_test(nan, nan)
|
||||
nan_test(nan, 0)
|
||||
nan_test(nan, 1)
|
||||
|
@ -118,7 +118,7 @@ class TestFloat < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_to_s
|
||||
inf = 1.0 / 0.0
|
||||
inf = Float::INFINITY
|
||||
assert_equal("Infinity", inf.to_s)
|
||||
assert_equal("-Infinity", (-inf).to_s)
|
||||
assert_equal("NaN", (inf / inf).to_s)
|
||||
|
@ -171,7 +171,7 @@ class TestFloat < Test::Unit::TestCase
|
|||
assert_equal([1.0, 0.0], 2.0.divmod(2.0))
|
||||
assert_raise(TypeError) { 2.0.divmod(nil) }
|
||||
|
||||
inf = 1.0 / 0.0
|
||||
inf = Float::INFINITY
|
||||
assert_raise(ZeroDivisionError) {inf.divmod(0)}
|
||||
|
||||
a, b = (2.0**32).divmod(1.0)
|
||||
|
@ -186,8 +186,8 @@ class TestFloat < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_eql
|
||||
inf = 1.0 / 0.0
|
||||
nan = inf / inf
|
||||
inf = Float::INFINITY
|
||||
nan = Float::NAN
|
||||
assert(1.0.eql?(1.0))
|
||||
assert(inf.eql?(inf))
|
||||
assert(!(nan.eql?(nan)))
|
||||
|
@ -200,8 +200,8 @@ class TestFloat < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_cmp
|
||||
inf = 1.0 / 0.0
|
||||
nan = inf / inf
|
||||
inf = Float::INFINITY
|
||||
nan = Float::NAN
|
||||
assert_equal(0, 1.0 <=> 1.0)
|
||||
assert_equal(1, 1.0 <=> 0.0)
|
||||
assert_equal(-1, 1.0 <=> 2.0)
|
||||
|
@ -232,14 +232,14 @@ class TestFloat < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_infinite_p
|
||||
inf = 1.0 / 0.0
|
||||
inf = Float::INFINITY
|
||||
assert(1, inf.infinite?)
|
||||
assert(1, (-inf).infinite?)
|
||||
assert_nil(1.0.infinite?)
|
||||
end
|
||||
|
||||
def test_finite_p
|
||||
inf = 1.0 / 0.0
|
||||
inf = Float::INFINITY
|
||||
assert(!(inf.finite?))
|
||||
assert(!((-inf).finite?))
|
||||
assert(1.0.finite?)
|
||||
|
@ -266,7 +266,7 @@ class TestFloat < Test::Unit::TestCase
|
|||
assert_equal(-2, (-2.0).round)
|
||||
assert_equal(-2, (-2.0).truncate)
|
||||
|
||||
inf = 1.0/0.0
|
||||
inf = Float::INFINITY
|
||||
assert_raise(FloatDomainError) { inf.floor }
|
||||
assert_raise(FloatDomainError) { inf.ceil }
|
||||
assert_raise(FloatDomainError) { inf.round }
|
||||
|
@ -413,7 +413,7 @@ class TestFloat < Test::Unit::TestCase
|
|||
assert(Float("1e10_00").infinite?)
|
||||
assert_raise(TypeError) { Float(nil) }
|
||||
o = Object.new
|
||||
def o.to_f; inf = 1.0/0.0; inf/inf; end
|
||||
def o.to_f; inf = Float::INFINITY; inf/inf; end
|
||||
assert(Float(o).nan?)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue