* numeric.c (coerce_rescue): prevent inspected String from GC.

* numeric.c (flo_eq, rb_dbl_cmp, flo_gt, flo_ge, flo_lt, flo_le,
  flo_eql): correct NaN comparison.  (ruby-bugs:PR#744)


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3671 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2003-04-11 06:37:48 +00:00
Родитель a700bcfafa
Коммит 76d7e7d54c
2 изменённых файлов: 43 добавлений и 20 удалений

Просмотреть файл

@ -1,3 +1,10 @@
Fri Apr 11 15:37:43 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* numeric.c (coerce_rescue): prevent inspected String from GC.
* numeric.c (flo_eq, rb_dbl_cmp, flo_gt, flo_ge, flo_lt, flo_le,
flo_eql): correct NaN comparison. (ruby-bugs:PR#744)
Fri Apr 11 14:48:47 2003 Yukihiro Matsumoto <matz@ruby-lang.org> Fri Apr 11 14:48:47 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* file.c (rb_stat): dereference using StringValuePtr(). * file.c (rb_stat): dereference using StringValuePtr().

Просмотреть файл

@ -93,9 +93,11 @@ static VALUE
coerce_rescue(x) coerce_rescue(x)
VALUE *x; VALUE *x;
{ {
volatile VALUE v;
rb_raise(rb_eTypeError, "%s can't be coerced into %s", rb_raise(rb_eTypeError, "%s can't be coerced into %s",
rb_special_const_p(x[1])? rb_special_const_p(x[1])?
RSTRING(rb_inspect(x[1]))->ptr: RSTRING(v = rb_inspect(x[1]))->ptr:
rb_obj_classname(x[1]), rb_obj_classname(x[1]),
rb_obj_classname(x[0])); rb_obj_classname(x[0]));
return Qnil; /* dummy */ return Qnil; /* dummy */
@ -506,17 +508,24 @@ static VALUE
flo_eq(x, y) flo_eq(x, y)
VALUE x, y; VALUE x, y;
{ {
double a, b;
switch (TYPE(y)) { switch (TYPE(y)) {
case T_FIXNUM: case T_FIXNUM:
if (RFLOAT(x)->value == FIX2LONG(y)) return Qtrue; b = FIX2LONG(y);
return Qfalse; break;
case T_BIGNUM: case T_BIGNUM:
return (RFLOAT(x)->value == rb_big2dbl(y))?Qtrue:Qfalse; b = rb_big2dbl(y);
break;
case T_FLOAT: case T_FLOAT:
return (RFLOAT(x)->value == RFLOAT(y)->value)?Qtrue:Qfalse; b = RFLOAT(y)->value;
break;
default: default:
return num_equal(x, y); return num_equal(x, y);
} }
a = RFLOAT(x)->value;
if (isnan(a) || isnan(b)) return Qfalse;
return (a == b)?Qtrue:Qfalse;
} }
static VALUE static VALUE
@ -541,6 +550,7 @@ VALUE
rb_dbl_cmp(a, b) rb_dbl_cmp(a, b)
double a, b; double a, b;
{ {
if (isnan(a) || isnan(b)) return Qnil;
if (a == b) return INT2FIX(0); if (a == b) return INT2FIX(0);
if (a > b) return INT2FIX(1); if (a > b) return INT2FIX(1);
if (a < b) return INT2FIX(-1); if (a < b) return INT2FIX(-1);
@ -596,6 +606,7 @@ flo_gt(x, y)
default: default:
return rb_num_coerce_cmp(x, y); return rb_num_coerce_cmp(x, y);
} }
if (isnan(a) || isnan(b)) return Qfalse;
return (a > b)?Qtrue:Qfalse; return (a > b)?Qtrue:Qfalse;
} }
@ -622,6 +633,7 @@ flo_ge(x, y)
default: default:
return rb_num_coerce_cmp(x, y); return rb_num_coerce_cmp(x, y);
} }
if (isnan(a) || isnan(b)) return Qfalse;
return (a >= b)?Qtrue:Qfalse; return (a >= b)?Qtrue:Qfalse;
} }
@ -648,6 +660,7 @@ flo_lt(x, y)
default: default:
return rb_num_coerce_cmp(x, y); return rb_num_coerce_cmp(x, y);
} }
if (isnan(a) || isnan(b)) return Qfalse;
return (a < b)?Qtrue:Qfalse; return (a < b)?Qtrue:Qfalse;
} }
@ -674,6 +687,7 @@ flo_le(x, y)
default: default:
return rb_num_coerce_cmp(x, y); return rb_num_coerce_cmp(x, y);
} }
if (isnan(a) || isnan(b)) return Qfalse;
return (a <= b)?Qtrue:Qfalse; return (a <= b)?Qtrue:Qfalse;
} }
@ -681,8 +695,12 @@ static VALUE
flo_eql(x, y) flo_eql(x, y)
VALUE x, y; VALUE x, y;
{ {
if (TYPE(y) == T_FLOAT && RFLOAT(x)->value == RFLOAT(y)->value) { if (TYPE(y) == T_FLOAT) {
return Qtrue; double a = RFLOAT(x)->value;
double b = RFLOAT(y)->value;
if (isnan(a) || isnan(b)) return Qfalse;
if (a == b) return Qtrue;
} }
return Qfalse; return Qfalse;
} }
@ -716,38 +734,36 @@ static VALUE
flo_is_nan_p(num) flo_is_nan_p(num)
VALUE num; VALUE num;
{ {
double value = RFLOAT(num)->value;
double value = RFLOAT(num)->value; return isnan(value) ? Qtrue : Qfalse;
return isnan(value) ? Qtrue : Qfalse;
} }
static VALUE static VALUE
flo_is_infinite_p(num) flo_is_infinite_p(num)
VALUE num; VALUE num;
{ {
double value = RFLOAT(num)->value; double value = RFLOAT(num)->value;
if (isinf(value)) { if (isinf(value)) {
return INT2FIX( value < 0 ? -1 : 1 ); return INT2FIX( value < 0 ? -1 : 1 );
} }
return Qnil; return Qnil;
} }
static VALUE static VALUE
flo_is_finite_p(num) flo_is_finite_p(num)
VALUE num; VALUE num;
{ {
double value = RFLOAT(num)->value; double value = RFLOAT(num)->value;
if (isinf(value) || isnan(value)) if (isinf(value) || isnan(value))
return Qfalse; return Qfalse;
return Qtrue; return Qtrue;
} }
static VALUE static VALUE
flo_floor(num) flo_floor(num)
VALUE num; VALUE num;