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 | fd815405aaec162d347aed3b6f99f0e6cfd454dd (patch) | |
| tree | 5ca7774f0f6950d814a213e2dbe5fa373d43205b /util.c | |
| parent | 8e190e23a36c83a20862be1155018f7f5658c61e (diff) | |
| download | ruby-fd815405aaec162d347aed3b6f99f0e6cfd454dd.tar.gz ruby-fd815405aaec162d347aed3b6f99f0e6cfd454dd.tar.xz ruby-fd815405aaec162d347aed3b6f99f0e6cfd454dd.zip | |
* util.c (ruby_strtod): try to reduce errors using powersOf10
table. [ruby-dev:28644]
git-svn-id: http://svn.ruby-lang.org/repos/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; } |
