зеркало из https://github.com/github/ruby.git
vm_insnhelper.c: avoid division by zero
same as r65642. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65678 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
21e1260fb9
Коммит
00b8b11858
|
@ -1755,6 +1755,7 @@ rb_num_negative_int_p(VALUE num)
|
|||
VALUE rb_float_abs(VALUE flt);
|
||||
VALUE rb_float_equal(VALUE x, VALUE y);
|
||||
VALUE rb_float_eql(VALUE x, VALUE y);
|
||||
VALUE rb_flo_div_flo(VALUE x, VALUE y);
|
||||
|
||||
#if USE_FLONUM
|
||||
#define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
|
||||
|
|
65
numeric.c
65
numeric.c
|
@ -1089,6 +1089,30 @@ flo_iszero(VALUE f)
|
|||
return RFLOAT_VALUE(f) == 0.0;
|
||||
}
|
||||
|
||||
static double
|
||||
double_div_double(double x, double y)
|
||||
{
|
||||
if (LIKELY(y != 0.0)) {
|
||||
return x / y;
|
||||
}
|
||||
else if (x == 0.0) {
|
||||
return nan("");
|
||||
}
|
||||
else {
|
||||
double z = signbit(y) ? -1.0 : 1.0;
|
||||
return x * z * HUGE_VAL;
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_flo_div_flo(VALUE x, VALUE y)
|
||||
{
|
||||
double num = RFLOAT_VALUE(x);
|
||||
double den = RFLOAT_VALUE(y);
|
||||
double ret = double_div_double(x, y);
|
||||
return DBL2NUM(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* float / other -> float
|
||||
|
@ -1099,52 +1123,25 @@ flo_iszero(VALUE f)
|
|||
static VALUE
|
||||
flo_div(VALUE x, VALUE y)
|
||||
{
|
||||
double den;
|
||||
double num = RFLOAT_VALUE(x);
|
||||
double sign = 1.0;
|
||||
double den;
|
||||
double ret;
|
||||
|
||||
if (RB_TYPE_P(y, T_FIXNUM)) {
|
||||
if (FIXNUM_ZERO_P(y)) {
|
||||
goto zerodiv;
|
||||
}
|
||||
else {
|
||||
den = FIX2LONG(y);
|
||||
goto nonzero;
|
||||
}
|
||||
den = FIX2LONG(y);
|
||||
}
|
||||
else if (RB_TYPE_P(y, T_BIGNUM)) {
|
||||
if (rb_bigzero_p(y)) {
|
||||
goto zerodiv;
|
||||
}
|
||||
else {
|
||||
den = rb_big2dbl(y);
|
||||
goto nonzero;
|
||||
}
|
||||
den = rb_big2dbl(y);
|
||||
}
|
||||
else if (RB_TYPE_P(y, T_FLOAT)) {
|
||||
if (flo_iszero(y)) {
|
||||
sign = signbit(RFLOAT_VALUE(y)) ? -1.0 : 1.0;
|
||||
goto zerodiv;
|
||||
}
|
||||
else {
|
||||
den = RFLOAT_VALUE(y);
|
||||
goto nonzero;
|
||||
}
|
||||
den = RFLOAT_VALUE(y);
|
||||
}
|
||||
else {
|
||||
return rb_num_coerce_bin(x, y, '/');
|
||||
}
|
||||
|
||||
nonzero:
|
||||
return DBL2NUM(num / den);
|
||||
|
||||
zerodiv:
|
||||
if (num == 0.0) {
|
||||
return DBL2NUM(nan(""));
|
||||
}
|
||||
else {
|
||||
return DBL2NUM(num * sign * HUGE_VAL);
|
||||
}
|
||||
ret = double_div_double(num, den);
|
||||
return DBL2NUM(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -3450,7 +3450,7 @@ vm_opt_div(VALUE recv, VALUE obj)
|
|||
}
|
||||
else if (FLONUM_2_P(recv, obj) &&
|
||||
BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
|
||||
return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
|
||||
return rb_flo_div_flo(recv, obj);
|
||||
}
|
||||
else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
|
||||
return Qundef;
|
||||
|
@ -3458,7 +3458,7 @@ vm_opt_div(VALUE recv, VALUE obj)
|
|||
else if (RBASIC_CLASS(recv) == rb_cFloat &&
|
||||
RBASIC_CLASS(obj) == rb_cFloat &&
|
||||
BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
|
||||
return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
|
||||
return rb_flo_div_flo(recv, obj);
|
||||
}
|
||||
else {
|
||||
return Qundef;
|
||||
|
|
Загрузка…
Ссылка в новой задаче