mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
avoid division by zero
* cvt(): use signbit() instead of 1/d < 0 * w_float(): ditto * ruby_float_step_size(): unit==0 check shall be prior to divisions * arith_seq_float_step_size(): ditto * rb_big_divide(): same as r65642 * fix_divide(): ditto * rb_big_fdiv_double(): ditto * fix_fdiv_double(): ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65751 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a3b92a5d92
commit
3a083985a4
5 changed files with 29 additions and 25 deletions
11
bignum.c
11
bignum.c
|
@ -6041,12 +6041,15 @@ rb_big_divide(VALUE x, VALUE y, ID op)
|
|||
}
|
||||
else if (RB_FLOAT_TYPE_P(y)) {
|
||||
if (op == '/') {
|
||||
return DBL2NUM(rb_big2dbl(x) / RFLOAT_VALUE(y));
|
||||
double dx = rb_big2dbl(x);
|
||||
return rb_flo_div_flo(DBL2NUM(dx), y);
|
||||
}
|
||||
else {
|
||||
VALUE v;
|
||||
double dy = RFLOAT_VALUE(y);
|
||||
if (dy == 0.0) rb_num_zerodiv();
|
||||
return rb_dbl2big(rb_big2dbl(x) / dy);
|
||||
v = rb_big_divide(x, y, '/');
|
||||
return rb_dbl2big(RFLOAT_VALUE(v));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -6179,6 +6182,7 @@ double
|
|||
rb_big_fdiv_double(VALUE x, VALUE y)
|
||||
{
|
||||
double dx, dy;
|
||||
VALUE v;
|
||||
|
||||
dx = big2dbl(x);
|
||||
if (FIXNUM_P(y)) {
|
||||
|
@ -6199,7 +6203,8 @@ rb_big_fdiv_double(VALUE x, VALUE y)
|
|||
else {
|
||||
return NUM2DBL(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
|
||||
}
|
||||
return dx / dy;
|
||||
v = rb_flo_div_flo(DBL2NUM(dx), DBL2NUM(dy));
|
||||
return NUM2DBL(v);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
|
11
enumerator.c
11
enumerator.c
|
@ -2790,15 +2790,16 @@ static double
|
|||
arith_seq_float_step_size(double beg, double end, double step, int excl)
|
||||
{
|
||||
double const epsilon = DBL_EPSILON;
|
||||
double n = (end - beg) / step;
|
||||
double err = (fabs(beg) + fabs(end) + fabs(end - beg)) / fabs(step) * epsilon;
|
||||
double n, err;
|
||||
|
||||
if (isinf(step)) {
|
||||
return step > 0 ? beg <= end : beg >= end;
|
||||
}
|
||||
if (step == 0) {
|
||||
return HUGE_VAL;
|
||||
}
|
||||
n = (end - beg) / step;
|
||||
err = (fabs(beg) + fabs(end) + fabs(end - beg)) / fabs(step) * epsilon;
|
||||
if (isinf(step)) {
|
||||
return step > 0 ? beg <= end : beg >= end;
|
||||
}
|
||||
if (err > 0.5) err = 0.5;
|
||||
if (excl) {
|
||||
if (n <= 0) return 0;
|
||||
|
|
|
@ -401,8 +401,8 @@ w_float(double d, struct dump_arg *arg)
|
|||
w_cstr("nan", arg);
|
||||
}
|
||||
else if (d == 0.0) {
|
||||
if (1.0/d < 0) w_cstr("-0", arg);
|
||||
else w_cstr("0", arg);
|
||||
if (signbit(d)) w_cstr("-0", arg);
|
||||
else w_cstr("0", arg);
|
||||
}
|
||||
else {
|
||||
int decpt, sign, digs, len = 0;
|
||||
|
|
26
numeric.c
26
numeric.c
|
@ -2485,15 +2485,16 @@ static double
|
|||
ruby_float_step_size(double beg, double end, double unit, int excl)
|
||||
{
|
||||
const double epsilon = DBL_EPSILON;
|
||||
double n = (end - beg)/unit;
|
||||
double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
|
||||
double n, err;
|
||||
|
||||
if (unit == 0) {
|
||||
return HUGE_VAL;
|
||||
}
|
||||
n= (end - beg)/unit;
|
||||
err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
|
||||
if (isinf(unit)) {
|
||||
return unit > 0 ? beg <= end : beg >= end;
|
||||
}
|
||||
if (unit == 0) {
|
||||
return HUGE_VAL;
|
||||
}
|
||||
if (err>0.5) err=0.5;
|
||||
if (excl) {
|
||||
if (n<=0) return 0;
|
||||
|
@ -3707,7 +3708,7 @@ fix_fdiv_double(VALUE x, VALUE y)
|
|||
return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), y);
|
||||
}
|
||||
else if (RB_TYPE_P(y, T_FLOAT)) {
|
||||
return (double)FIX2LONG(x) / RFLOAT_VALUE(y);
|
||||
return double_div_double(FIX2LONG(x), RFLOAT_VALUE(y));
|
||||
}
|
||||
else {
|
||||
return NUM2DBL(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
|
||||
|
@ -3777,19 +3778,16 @@ fix_divide(VALUE x, VALUE y, ID op)
|
|||
return rb_big_div(x, y);
|
||||
}
|
||||
else if (RB_TYPE_P(y, T_FLOAT)) {
|
||||
{
|
||||
double div;
|
||||
|
||||
if (op == '/') {
|
||||
div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
|
||||
return DBL2NUM(div);
|
||||
double d = FIX2LONG(x);
|
||||
return rb_flo_div_flo(DBL2NUM(d), y);
|
||||
}
|
||||
else {
|
||||
VALUE v;
|
||||
if (RFLOAT_VALUE(y) == 0) rb_num_zerodiv();
|
||||
div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
|
||||
return rb_dbl2big(floor(div));
|
||||
v = fix_divide(x, y, '/');
|
||||
return flo_floor(0, 0, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (RB_TYPE_P(y, T_RATIONAL) &&
|
||||
|
|
|
@ -1250,7 +1250,7 @@ cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch, int *l
|
|||
if (value < 0) {
|
||||
value = -value;
|
||||
*sign = '-';
|
||||
} else if (value == 0.0 && 1.0/value < 0) {
|
||||
} else if (value == 0.0 && signbit(value)) {
|
||||
*sign = '-';
|
||||
} else {
|
||||
*sign = '\000';
|
||||
|
|
Loading…
Reference in a new issue