mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* numeric.c (flo_round): Make Float#round round big values [bug #5272]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33186 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
269de36cd0
commit
75c42535c9
2 changed files with 21 additions and 34 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Mon Sep 5 05:13:22 2011 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||||
|
|
||||||
|
* numeric.c (flo_round): Make Float#round round big values [bug
|
||||||
|
#5272]
|
||||||
|
|
||||||
Mon Sep 5 04:28:25 2011 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
Mon Sep 5 04:28:25 2011 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||||
|
|
||||||
* numeric.c (int_round): Integer#round always returns an Integer [Bug
|
* numeric.c (int_round): Integer#round always returns an Integer [Bug
|
||||||
|
|
50
numeric.c
50
numeric.c
|
@ -1494,6 +1494,9 @@ int_round_0(VALUE num, int ndigits)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
flo_truncate(VALUE num);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* flt.round([ndigits]) -> integer or float
|
* flt.round([ndigits]) -> integer or float
|
||||||
|
@ -1531,13 +1534,18 @@ flo_round(int argc, VALUE *argv, VALUE num)
|
||||||
double number, f;
|
double number, f;
|
||||||
int ndigits = 0;
|
int ndigits = 0;
|
||||||
int binexp;
|
int binexp;
|
||||||
long val;
|
|
||||||
enum {float_dig = DBL_DIG+2};
|
enum {float_dig = DBL_DIG+2};
|
||||||
|
|
||||||
if (argc > 0 && rb_scan_args(argc, argv, "01", &nd) == 1) {
|
if (argc > 0 && rb_scan_args(argc, argv, "01", &nd) == 1) {
|
||||||
ndigits = NUM2INT(nd);
|
ndigits = NUM2INT(nd);
|
||||||
}
|
}
|
||||||
|
if (ndigits < 0) {
|
||||||
|
return int_round_0(flo_truncate(num), ndigits);
|
||||||
|
}
|
||||||
number = RFLOAT_VALUE(num);
|
number = RFLOAT_VALUE(num);
|
||||||
|
if (ndigits == 0) {
|
||||||
|
return dbl2ival(number);
|
||||||
|
}
|
||||||
frexp(number, &binexp);
|
frexp(number, &binexp);
|
||||||
|
|
||||||
/* Let `exp` be such that `number` is written as:"0.#{digits}e#{exp}",
|
/* Let `exp` be such that `number` is written as:"0.#{digits}e#{exp}",
|
||||||
|
@ -1557,41 +1565,15 @@ flo_round(int argc, VALUE *argv, VALUE num)
|
||||||
So if ndigits + binexp/(4 or 3) >= float_dig, the result is number
|
So if ndigits + binexp/(4 or 3) >= float_dig, the result is number
|
||||||
If ndigits + binexp/(3 or 4) < 0 the result is 0
|
If ndigits + binexp/(3 or 4) < 0 the result is 0
|
||||||
*/
|
*/
|
||||||
if (isinf(number) || isnan(number)) {
|
if (isinf(number) || isnan(number) ||
|
||||||
/* Do nothing */
|
(((long)ndigits - float_dig) * (3 + (binexp > 0)) + binexp >= 0)) {
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
else if ((long)ndigits * (4 - (binexp > 0)) + binexp < 0) {
|
if ((long)ndigits * (4 - (binexp > 0)) + binexp < 0) {
|
||||||
number = 0;
|
return DBL2NUM(0);
|
||||||
}
|
}
|
||||||
else if (((long)ndigits - float_dig) * (3 + (binexp > 0)) + binexp < 0) {
|
f = pow(10, ndigits);
|
||||||
f = pow(10, abs(ndigits));
|
return DBL2NUM(round(number * f) / f);
|
||||||
if (ndigits < 0) {
|
|
||||||
double absnum = fabs(number);
|
|
||||||
if (absnum < f) return INT2FIX(0);
|
|
||||||
if (!FIXABLE(number)) {
|
|
||||||
VALUE f10 = int_pow(10, -ndigits);
|
|
||||||
VALUE n10 = f10;
|
|
||||||
if (number < 0) {
|
|
||||||
f10 = FIXNUM_P(f10) ? fix_uminus(f10) : rb_big_uminus(f10);
|
|
||||||
}
|
|
||||||
num = rb_big_idiv(rb_dbl2big(absnum), n10);
|
|
||||||
return FIXNUM_P(num) ? fix_mul(num, f10) : rb_big_mul(num, f10);
|
|
||||||
}
|
|
||||||
number /= f;
|
|
||||||
}
|
|
||||||
else number *= f;
|
|
||||||
number = round(number);
|
|
||||||
if (ndigits < 0) number *= f;
|
|
||||||
else number /= f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ndigits > 0) return DBL2NUM(number);
|
|
||||||
|
|
||||||
if (!FIXABLE(number)) {
|
|
||||||
return rb_dbl2big(number);
|
|
||||||
}
|
|
||||||
val = (long)number;
|
|
||||||
return LONG2FIX(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue