From a2fbd80a473071f76687dda5fda7dbbea7efde9f Mon Sep 17 00:00:00 2001 From: ksss Date: Sat, 19 Nov 2016 09:29:22 +0900 Subject: Fix Range#size results --- mrbgems/mruby-range-ext/src/range.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'mrbgems/mruby-range-ext/src/range.c') diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index 4d6f1684f..87bdab228 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -1,6 +1,7 @@ #include #include #include +#include static mrb_bool r_le(mrb_state *mrb, mrb_value a, mrb_value b) @@ -140,9 +141,11 @@ mrb_range_size(mrb_state *mrb, mrb_value range) mrb_value beg, end; double beg_f, end_f; mrb_bool num_p = TRUE; + mrb_bool excl; beg = r->edges->beg; end = r->edges->end; + excl = r->excl; if (mrb_fixnum_p(beg)) { beg_f = (double)mrb_fixnum(beg); } @@ -162,14 +165,24 @@ mrb_range_size(mrb_state *mrb, mrb_value range) num_p = FALSE; } if (num_p) { - double f; - - if (beg_f > end_f) return mrb_fixnum_value(0); - f = end_f - beg_f; - if (!r->excl) { - return mrb_fixnum_value((mrb_int)ceil(f + 1)); + double n = end_f - beg_f; + double err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * DBL_EPSILON; + + if (err>0.5) err=0.5; + if (excl) { + if (n<=0) return mrb_fixnum_value(0); + if (n<1) + n = 0; + else + n = floor(n - err); + } + else { + if (n<0) return mrb_fixnum_value(0); + n = floor(n + err); } - return mrb_fixnum_value((mrb_int)ceil(f)); + if (isinf(n+1)) + return mrb_float_value(mrb, INFINITY); + return mrb_fixnum_value(n+1); } return mrb_nil_value(); } -- cgit v1.2.3 From 22390aa1c8e17135e1d298e5e66776c77234c0b5 Mon Sep 17 00:00:00 2001 From: ksss Date: Sat, 19 Nov 2016 23:24:20 +0900 Subject: Use mrb_float instead of double --- mrbgems/mruby-range-ext/src/range.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'mrbgems/mruby-range-ext/src/range.c') diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index 87bdab228..1d9312b03 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -139,7 +139,7 @@ mrb_range_size(mrb_state *mrb, mrb_value range) { struct RRange *r = mrb_range_ptr(range); mrb_value beg, end; - double beg_f, end_f; + mrb_float beg_f, end_f; mrb_bool num_p = TRUE; mrb_bool excl; @@ -147,7 +147,7 @@ mrb_range_size(mrb_state *mrb, mrb_value range) end = r->edges->end; excl = r->excl; if (mrb_fixnum_p(beg)) { - beg_f = (double)mrb_fixnum(beg); + beg_f = (mrb_float)mrb_fixnum(beg); } else if (mrb_float_p(beg)) { beg_f = mrb_float(beg); @@ -156,7 +156,7 @@ mrb_range_size(mrb_state *mrb, mrb_value range) num_p = FALSE; } if (mrb_fixnum_p(end)) { - end_f = (double)mrb_fixnum(end); + end_f = (mrb_float)mrb_fixnum(end); } else if (mrb_float_p(end)) { end_f = mrb_float(end); @@ -165,8 +165,8 @@ mrb_range_size(mrb_state *mrb, mrb_value range) num_p = FALSE; } if (num_p) { - double n = end_f - beg_f; - double err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * DBL_EPSILON; + mrb_float n = end_f - beg_f; + mrb_float err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * DBL_EPSILON; if (err>0.5) err=0.5; if (excl) { -- cgit v1.2.3