From 7b724e750f55227e455a618f044e057920b5f671 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 16 May 2006 23:24:08 +0000 Subject: [PATCH] * 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 --- ChangeLog | 5 +++++ util.c | 52 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9398bfb255..aa901fc991 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed May 17 08:17:15 2006 Yukihiro Matsumoto + + * util.c (ruby_strtod): try to reduce errors using powersOf10 + table. [ruby-dev:28644] + Tue May 16 15:34:18 2006 Yukihiro Matsumoto * re.c (rb_reg_initialize): should not allow modifying literal diff --git a/util.c b/util.c index 9424fa58e3..6d1c9bc496 100644 --- a/util.c +++ b/util.c @@ -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; }