aboutsummaryrefslogtreecommitdiffstats
path: root/numeric.c
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-12 03:26:39 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-12 03:26:39 +0000
commit00b8b11858785439785c0f6805ea4b6910070020 (patch)
tree2bdd01ea10b74ce28396a3caa0b69f1ede365ac4 /numeric.c
parent21e1260fb94f7d339ee60eedbba1975113ade7f1 (diff)
downloadruby-00b8b11858785439785c0f6805ea4b6910070020.tar.gz
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
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c65
1 files changed, 31 insertions, 34 deletions
diff --git a/numeric.c b/numeric.c
index 47dbf722f1..6d098368df 100644
--- a/numeric.c
+++ b/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);
}
/*