diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-05-16 23:24:08 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-05-16 23:24:08 +0000 |
commit | 7b724e750f55227e455a618f044e057920b5f671 (patch) | |
tree | 5ca7774f0f6950d814a213e2dbe5fa373d43205b /util.c | |
parent | c606447c00af509f26f4feec95332f832bcc4935 (diff) |
* util.c (ruby_strtod): try to reduce errors using powersOf10
table. [ruby-dev:28644]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@10160 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 52 |
1 files changed, 31 insertions, 21 deletions
@@ -684,6 +684,18 @@ ruby_getcwd() #define MDMINEXPT DBL_MIN_EXP #define MDMAXEXPT DBL_MAX_EXP +static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ + 10.0, /* is 10^2^i. Used to convert decimal */ + 100.0, /* exponents into floating-point numbers. */ + 1.0e4, + 1.0e8, + 1.0e16, + 1.0e32, + 1.0e64, + 1.0e128, + 1.0e256 +}; + /* *---------------------------------------------------------------------- * @@ -724,7 +736,7 @@ ruby_strtod(string, endPtr) * address here. */ { int sign, expSign = Qfalse; - double fraction = 0.0, dblExp; + double fraction = 0.0, dblExp, *d; register const char *p; register int c; int exp = 0; /* Exponent read from "EX" field. */ @@ -891,18 +903,17 @@ ruby_strtod(string, endPtr) else { expSign = Qfalse; } - dblExp = 10.0; - while (exp) { + dblExp = 1.0; + for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { if (exp & 01) { - if (expSign) { - frac1 /= dblExp; - } - else { - frac1 *= dblExp; - } + dblExp *= *d; } - exp >>= 1; - dblExp *= dblExp; + } + if (expSign) { + frac1 /= dblExp; + } + else { + frac1 *= dblExp; } exp = fracExp; if (exp < 0) { @@ -912,18 +923,17 @@ ruby_strtod(string, endPtr) else { expSign = Qfalse; } - dblExp = 10.0; - while (exp) { + dblExp = 1.0; + for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { if (exp & 01) { - if (expSign) { - frac2 /= dblExp; - } - else { - frac2 *= dblExp; - } + dblExp *= *d; } - exp >>= 1; - dblExp *= dblExp; + } + if (expSign) { + frac2 /= dblExp; + } + else { + frac2 *= dblExp; } fraction = frac1 + frac2; } |