summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-09-01 16:07:16 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-09-01 16:07:16 +0000
commitc4eb2983bac76f60e0d3fe958b74237e2aac90d6 (patch)
tree296f74363982b68c768e526785d23509c5779993 /numeric.c
parent43284b6bf8324a762808537d5cd2c0774b662a84 (diff)
* numeric.c (flo_round): substitute machine dependent magic number.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/numeric.c b/numeric.c
index 176b589b0b..201dfabd28 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1493,17 +1493,18 @@ flo_round(int argc, VALUE *argv, VALUE num)
int ndigits = 0;
int binexp;
long val;
+ enum {float_dig = DBL_DIG+2};
if (argc > 0 && rb_scan_args(argc, argv, "01", &nd) == 1) {
ndigits = NUM2INT(nd);
}
number = RFLOAT_VALUE(num);
- frexp (number , &binexp);
+ frexp(number, &binexp);
/* Let `exp` be such that `number` is written as:"0.#{digits}e#{exp}",
i.e. such that 10 ** (exp - 1) <= |number| < 10 ** exp
- Recall that up to 17 digits can be needed to represent a double,
- so if ndigits + exp >= 17, the intermediate value (number * 10 ** ndigits)
+ Recall that up to float_dig digits can be needed to represent a double,
+ so if ndigits + exp >= float_dig, the intermediate value (number * 10 ** ndigits)
will be an integer and thus the result is the original number.
If ndigits + exp <= 0, the result is 0 or "1e#{exp}", so
if ndigits + exp < 0, the result is 0.
@@ -1514,7 +1515,7 @@ flo_round(int argc, VALUE *argv, VALUE num)
10 ** (binexp/4 - 1) < |number| < 10 ** (binexp/3)
binexp/4 <= exp <= binexp/3
If binexp <= 0, swap the /4 and the /3
- So if ndigits + binexp/(4 or 3) >= 17, 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 (isinf(number) || isnan(number)) {
@@ -1523,7 +1524,7 @@ flo_round(int argc, VALUE *argv, VALUE num)
else if ((long)ndigits * (4 - (binexp > 0)) + binexp < 0) {
number = 0;
}
- else if (((long)ndigits - 17) * (3 + (binexp > 0)) + binexp < 0) {
+ else if (((long)ndigits - float_dig) * (3 + (binexp > 0)) + binexp < 0) {
f = pow(10, abs(ndigits));
if (ndigits < 0) {
double absnum = fabs(number);