mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
numeric.c: round nearly middle value
* numeric.c (flo_round): [EXPERIMENTAL] adjust the case that the receiver is close to the exact but unrepresentable middle value of two values in the given precision. http://d.hatena.ne.jp/hnw/20160702 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55604 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
415059abf1
commit
9bb27fa318
3 changed files with 21 additions and 2 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Thu Jul 7 16:37:53 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* numeric.c (flo_round): [EXPERIMENTAL] adjust the case that the
|
||||||
|
receiver is close to the exact but unrepresentable middle value
|
||||||
|
of two values in the given precision.
|
||||||
|
http://d.hatena.ne.jp/hnw/20160702
|
||||||
|
|
||||||
Thu Jul 7 16:31:07 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Jul 7 16:31:07 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* io.c (rb_io_s_foreach, rb_io_s_readlines): convert arguments
|
* io.c (rb_io_s_foreach, rb_io_s_readlines): convert arguments
|
||||||
|
|
11
numeric.c
11
numeric.c
|
@ -1990,7 +1990,7 @@ rb_int_truncate(VALUE num, int ndigits)
|
||||||
static VALUE
|
static VALUE
|
||||||
flo_round(int argc, VALUE *argv, VALUE num)
|
flo_round(int argc, VALUE *argv, VALUE num)
|
||||||
{
|
{
|
||||||
double number, f;
|
double number, f, x;
|
||||||
int ndigits = 0;
|
int ndigits = 0;
|
||||||
|
|
||||||
if (rb_check_arity(argc, 0, 1)) {
|
if (rb_check_arity(argc, 0, 1)) {
|
||||||
|
@ -2005,7 +2005,14 @@ flo_round(int argc, VALUE *argv, VALUE num)
|
||||||
}
|
}
|
||||||
if (float_invariant_round(number, ndigits, &num)) return num;
|
if (float_invariant_round(number, ndigits, &num)) return num;
|
||||||
f = pow(10, ndigits);
|
f = pow(10, ndigits);
|
||||||
return DBL2NUM(round(number * f) / f);
|
x = round(number * f);
|
||||||
|
if (x > 0) {
|
||||||
|
if ((x + 0.5) / f <= number) x += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((x - 0.5) / f >= number) x -= 1;
|
||||||
|
}
|
||||||
|
return DBL2NUM(x / f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -447,6 +447,11 @@ class TestFloat < Test::Unit::TestCase
|
||||||
assert_raise(TypeError) {1.0.round(nil)}
|
assert_raise(TypeError) {1.0.round(nil)}
|
||||||
def (prec = Object.new).to_int; 2; end
|
def (prec = Object.new).to_int; 2; end
|
||||||
assert_equal(1.0, 0.998.round(prec))
|
assert_equal(1.0, 0.998.round(prec))
|
||||||
|
|
||||||
|
assert_equal(+5.02, +5.015.round(2))
|
||||||
|
assert_equal(-5.02, -5.015.round(2))
|
||||||
|
assert_equal(+1.26, +1.255.round(2))
|
||||||
|
assert_equal(-1.26, -1.255.round(2))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_floor_with_precision
|
def test_floor_with_precision
|
||||||
|
|
Loading…
Reference in a new issue