summaryrefslogtreecommitdiffhomepage
path: root/src/numeric.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-05-27 23:51:22 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-05-27 23:51:22 +0900
commit8e390cccaef082e2b5034a8147dd62bd2391da25 (patch)
treead3a5a90fab0390c314dd8890fbfda39c4ae6a27 /src/numeric.c
parent34dd258c638bfc9e8ffac6621f3918faff3d797f (diff)
downloadmruby-8e390cccaef082e2b5034a8147dd62bd2391da25.tar.gz
mruby-8e390cccaef082e2b5034a8147dd62bd2391da25.zip
Fixed rounding functions (round,ceil,floor,truncate) in MRB_INT64.
They didn't work well with inexact numbers (inf,nan). Fix #3671
Diffstat (limited to 'src/numeric.c')
-rw-r--r--src/numeric.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/src/numeric.c b/src/numeric.c
index 2f2a76517..11995cac1 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -497,6 +497,17 @@ flo_finite_p(mrb_state *mrb, mrb_value num)
return mrb_bool_value(isfinite(mrb_float(num)));
}
+void
+mrb_check_num_exact(mrb_state *mrb, mrb_float num)
+{
+ if (isinf(num)) {
+ mrb_raise(mrb, E_FLOATDOMAIN_ERROR, num < 0 ? "-Infinity" : "Infinity");
+ }
+ if (isnan(num)) {
+ mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
+ }
+}
+
/* 15.2.9.3.10 */
/*
* call-seq:
@@ -515,6 +526,7 @@ flo_floor(mrb_state *mrb, mrb_value num)
{
mrb_float f = floor(mrb_float(num));
+ mrb_check_num_exact(mrb, f);
if (!FIXABLE_FLOAT(f)) {
return mrb_float_value(mrb, f);
}
@@ -540,6 +552,7 @@ flo_ceil(mrb_state *mrb, mrb_value num)
{
mrb_float f = ceil(mrb_float(num));
+ mrb_check_num_exact(mrb, f);
if (!FIXABLE_FLOAT(f)) {
return mrb_float_value(mrb, f);
}
@@ -587,14 +600,10 @@ flo_round(mrb_state *mrb, mrb_value num)
mrb_get_args(mrb, "|i", &ndigits);
number = mrb_float(num);
- if (isinf(number)) {
- if (0 < ndigits) return num;
- else mrb_raise(mrb, E_FLOATDOMAIN_ERROR, number < 0 ? "-Infinity" : "Infinity");
- }
- if (isnan(number)) {
- if (0 < ndigits) return num;
- else mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
+ if (0 < ndigits && (isinf(number) || isnan(number))) {
+ return num;
}
+ mrb_check_num_exact(mrb, number);
f = 1.0;
i = ndigits >= 0 ? ndigits : -ndigits;
@@ -631,17 +640,6 @@ flo_round(mrb_state *mrb, mrb_value num)
return mrb_fixnum_value((mrb_int)number);
}
-void
-mrb_check_num_exact(mrb_state *mrb, mrb_float num)
-{
- if (isinf(num)) {
- mrb_raise(mrb, E_FLOATDOMAIN_ERROR, num < 0 ? "-Infinity" : "Infinity");
- }
- if (isnan(num)) {
- mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
- }
-}
-
/* 15.2.9.3.14 */
/* 15.2.9.3.15 */
/*
@@ -661,8 +659,8 @@ flo_truncate(mrb_state *mrb, mrb_value num)
if (f > 0.0) f = floor(f);
if (f < 0.0) f = ceil(f);
+ mrb_check_num_exact(mrb, f);
if (!FIXABLE_FLOAT(f)) {
- mrb_check_num_exact(mrb, f);
return mrb_float_value(mrb, f);
}
return mrb_fixnum_value((mrb_int)f);