From: "H.Yamamoto" Date: 2004-05-06T19:53:50+09:00 Subject: [ruby-dev:23465] Re [ruby-talk:99318] 0.0000000000000000001 == 0.0 should be false 山本です。 [ruby-talk:99318] で報告されていたバグを修正してみました。 # 修正前(18番目以降の数字を無条件に切り捨てていた) E:\ruby-cvs\ruby>..\miniruby -ve "p 0.0000000000000000001" ruby 1.9.0 (2004-04-27) [i386-bccwin32] 0.0 # 修正後(有効桁数を数えるときは、先頭の 0 は数えてはいけないので、そのように修正) E:\ruby-cvs\ruby>miniruby -e "p 0.0000000000000000001" 1e-19 Index: util.c =================================================================== RCS file: /ruby/ruby/util.c,v retrieving revision 1.41 diff -u -w -b -p -r1.41 util.c --- util.c 29 Jan 2004 14:54:14 -0000 1.41 +++ util.c 6 May 2004 10:49:32 -0000 @@ -744,9 +744,10 @@ ruby_strtod(string, endPtr) * unnecessary overflow on I alone). In this * case, fracExp is incremented one for each * dropped digit. */ - int mantSize; /* Number of digits in mantissa. */ - int decPt; /* Number of mantissa digits BEFORE decimal - * point. */ + int mantSize = 0; /* Number of digits in mantissa. */ + int decPt = 0; /* mantissa has decimal point. */ + const char *pMant; /* Temporarily holds location of mantissa + * in string. (valid only when mantSize > 0) */ const char *pExp; /* Temporarily holds location of exponent * in string. */ @@ -770,28 +771,30 @@ ruby_strtod(string, endPtr) sign = FALSE; } - /* skip preceding zeros */ - if (*p == '0') { - while (*p == '0') - p++; - p--; - } - /* * Count the number of digits in the mantissa (including the decimal * point), and also locate the decimal point. */ - decPt = -1; - for (mantSize = 0; ; mantSize += 1) { - c = *p; + for ( ; c = *p; p++) { if (!ISDIGIT(c)) { - if ((c != '.') || (decPt >= 0)) { + if (c != '.' || decPt) { break; } - decPt = mantSize; + decPt = 1; + } + else { + if (decPt) { /* in fractional part */ + fracExp -= 1; + } + if (mantSize) { /* already in mantissa */ + mantSize += 1; + } + else if (c != '0') { /* have entered mantissa */ + mantSize += 1; + pMant = p; + } } - p += 1; } /* @@ -802,19 +805,10 @@ ruby_strtod(string, endPtr) */ pExp = p; - p -= mantSize; - if (decPt < 0) { - decPt = mantSize; - } - else { - mantSize -= 1; /* One of the digits was the point. */ - } + p = pMant; if (mantSize > 18) { - fracExp = decPt - 18; + fracExp += (mantSize - 18); mantSize = 18; - } - else { - fracExp = decPt - mantSize; } if (mantSize == 0) { fraction = 0.0;