aboutsummaryrefslogtreecommitdiffstats
path: root/numeric.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-11-25 06:28:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-11-25 06:28:00 +0000
commitcc8782ccc86563b5aae5713863a72806d2a1400d (patch)
treed85aad8b66468b69730c9a85362879b56f5aa41a /numeric.c
parent7e49e3a40acfb155afc41f49f82e19dd0336fb3f (diff)
downloadruby-cc8782ccc86563b5aae5713863a72806d2a1400d.tar.gz
round-down
* numeric.c (round_half_down, int_round_half_down): support round-down mode. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56897 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/numeric.c b/numeric.c
index 38668ec0d9..d2c9cf701b 100644
--- a/numeric.c
+++ b/numeric.c
@@ -119,6 +119,31 @@ round_half_up(double x, double s)
}
static double
+round_half_down(double x, double s)
+{
+ double f, xs = x * s;
+
+#ifdef HAVE_ROUND
+ f = round(xs);
+#endif
+ if (x > 0) {
+#ifndef HAVE_ROUND
+ f = ceil(xs);
+#endif
+ if ((double)((f - 0.5) / s) >= x) f -= 1;
+ x = f;
+ }
+ else {
+#ifndef HAVE_ROUND
+ f = floor(xs);
+#endif
+ if ((double)((f + 0.5) / s) <= x) f += 1;
+ x = f;
+ }
+ return x;
+}
+
+static double
round_half_even(double x, double s)
{
double f, d, xs = x * s;
@@ -213,6 +238,8 @@ rb_num_get_rounding_option(VALUE opts)
case 4:
if (rb_memcicmp(s, "even", 4) == 0)
return RUBY_NUM_ROUND_HALF_EVEN;
+ if (strncasecmp(s, "down", 4) == 0)
+ return RUBY_NUM_ROUND_HALF_DOWN;
break;
}
invalid:
@@ -2040,6 +2067,12 @@ int_round_half_up(SIGNED_VALUE x, SIGNED_VALUE y)
return (x + y / 2) / y * y;
}
+static SIGNED_VALUE
+int_round_half_down(SIGNED_VALUE x, SIGNED_VALUE y)
+{
+ return (x + y / 2 - 1) / y * y;
+}
+
static int
int_half_p_half_even(VALUE num, VALUE n, VALUE f)
{
@@ -2052,6 +2085,12 @@ int_half_p_half_up(VALUE num, VALUE n, VALUE f)
return int_pos_p(num);
}
+static int
+int_half_p_half_down(VALUE num, VALUE n, VALUE f)
+{
+ return int_neg_p(num);
+}
+
/*
* Assumes num is an Integer, ndigits <= 0
*/