https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112013-04-20T11:31:34ZRuby Issue Tracking SystemRuby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=387792013-04-20T11:31:34Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>Just -1.1505945e-5 is not accurately representable in binary format.</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=387902013-04-21T07:41:03Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul><li><strong>Status</strong> changed from <i>Rejected</i> to <i>Open</i></li><li><strong>Priority</strong> changed from <i>3</i> to <i>Normal</i></li></ul><p>Actually, this is a bug.</p>
<ol>
<li>
<p>Float#to_s must be minimal while round-tripping. This is clearly not the case in the given examples.</p>
</li>
<li>
<p>Float#to_s must be platform independent</p>
</li>
</ol>
<p>On OS X, I get the correct string conversion.<br>
$ ruby -v -e 'p(-1.1505945E-5)'<br>
ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-darwin10.8.0]<br>
-1.1505945e-05<br>
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin10.8.0]<br>
-1.1505945e-05</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=387912013-04-21T10:30:57Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>marcandre (Marc-Andre Lafortune) wrote:</p>
<blockquote>
<p>Actually, this is a bug.</p>
<ol>
<li>Float#to_s must be minimal while round-tripping. This is clearly not the case in the given examples.</li>
</ol>
</blockquote>
<p>If the given value cannot be represented by binary, it won't be minimal while round-tripping.</p>
<blockquote>
<ol start="2">
<li>Float#to_s must be platform independent</li>
</ol>
</blockquote>
<p>double calculation itself is platform dependent.<br>
see also x87 and if you want ruby for x86 to behave as x64 specify -msse2 -mfpmath=sse for gcc.<br>
<a href="http://en.wikipedia.org/wiki/X87" class="external">http://en.wikipedia.org/wiki/X87</a></p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=387922013-04-21T12:44:56ZStudent (Nathan Zook)blogger@pierian-spring.net
<ul></ul><p>Double calculations are not in themselves platform dependent except in the IEEE-754 boundary cases. These boundaries are extremely narrow, such as half way from min normal to max denormal. If there is a platform dependence, then the libraries involved must be either setting the hardware control bits differently, or computing the values differently. The value in question is no where near the double precision boundary, so there must be a difference in either how the libraries are doing the conversion or in how the rounding bits are being set.</p>
<p>This may be worth investigation to see the source of the difference.</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=387932013-04-21T15:57:14Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>Student (Nathan Zook) wrote:</p>
<blockquote>
<p>Double calculations are not in themselves platform dependent except in the IEEE-754 boundary cases. These boundaries are extremely narrow, such as half way from min normal to max denormal. If there is a platform dependence, then the libraries involved must be either setting the hardware control bits differently, or computing the values differently. The value in question is no where near the double precision boundary, so there must be a difference in either how the libraries are doing the conversion or in how the rounding bits are being set.</p>
<p>This may be worth investigation to see the source of the difference.</p>
</blockquote>
<p>Learn 80bit precision of x87's FPU as I wrote in <a href="/issues/8299">[ruby-core:54485]</a>.</p>
<p>Moreover there's non IEEE-754 fp for example VAX.</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=387972013-04-21T23:26:07Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Tracker</strong> changed from <i>Backport</i> to <i>Bug</i></li><li><strong>Project</strong> changed from <i>Backport200</i> to <i>Ruby master</i></li></ul> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388012013-04-22T01:57:48Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul><li><strong>Status</strong> changed from <i>Rejected</i> to <i>Open</i></li><li><strong>ruby -v</strong> set to <i>trunk</i></li></ul><p>naruse (Yui NARUSE) wrote:</p>
<blockquote>
<blockquote>
<ol>
<li>Float#to_s must be minimal while round-tripping. This is clearly not the case in the given examples.</li>
</ol>
</blockquote>
<p>If the given value cannot be represented by binary, it won't be minimal while round-tripping.</p>
</blockquote>
<p>Sorry, I do not understand what you said. What I meant to say is (<a href="/issues/3273">[ruby-core:30145]</a>):</p>
<p>For any float f, the two following conditions should hold:<br>
(1) f.to_s.to_f == f (round trips)<br>
(2) f.to_s.chop.to_f != f (minimal)</p>
<p>The second condition is a simplification; if the string representation is in scientific notation, than the character to remove would be the one just before the "e". Also, if the string representation ends with ".0", then it is minimal.</p>
<blockquote>
<blockquote>
<ol start="2">
<li>Float#to_s must be platform independent</li>
</ol>
</blockquote>
<p>double calculation itself is platform dependent.</p>
</blockquote>
<p>Sorry, I should have specified "...on IEEE 754 platforms", which is the case for mgwin32, right?</p>
<blockquote>
<p>Moreover there's non IEEE-754 fp for example VAX.</p>
</blockquote>
<p>We don't support VAX, as you wrote yourself in <a href="/issues/5884">[ruby-core:42077]</a>, so how is this relevant exactly?</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388022013-04-22T01:58:52Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>Can anyone on [i386-mingw32] report which of the two following is false:</p>
<pre><code>-1.1505945e-05 != -1.1505945000000001e-05
"\xBE\xE8!5\n\x1D\x17A".unpack('G').first.to_s == "-1.1505945e-05"
</code></pre>
<p>If the first is false, then parsing is buggy and I presume you get:</p>
<pre><code>f = "\xBE\xE8!5\n\x1D\x17A".unpack('G').first
f.to_s.to_f == f # => false, should be true for any float f (not NaN or inf).
</code></pre>
<p>If the second is false, then conversion to string is buggy and I imagine you will get:</p>
<pre><code>f = -1.1505945e-05
g = -1.1505945000000001e-05
f == g # => false
f.to_s == g.to_s # => true (should be consistent for any floats f & g (not NaN))
</code></pre> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388032013-04-22T11:18:28Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>I wrote this is because of x87.<br>
Did you read it?</p>
<p>marcandre (Marc-Andre Lafortune) wrote:</p>
<blockquote>
<p>naruse (Yui NARUSE) wrote:</p>
<blockquote>
<blockquote>
<ol>
<li>Float#to_s must be minimal while round-tripping. This is clearly not the case in the given examples.</li>
</ol>
</blockquote>
<p>If the given value cannot be represented by binary, it won't be minimal while round-tripping.</p>
</blockquote>
<p>Sorry, I do not understand what you said. What I meant to say is (<a href="/issues/3273">[ruby-core:30145]</a>):</p>
<p>For any float f, the two following conditions should hold:<br>
(1) f.to_s.to_f == f (round trips)</p>
</blockquote>
<p>Yeah, unless you transfer the result of to_s to another environment.</p>
<blockquote>
<p>(2) f.to_s.chop.to_f != f (minimal)</p>
<p>The second condition is a simplification; if the string representation is in scientific notation, than the character to remove would be the one just before the "e". Also, if the string representation ends with ".0", then it is minimal.</p>
</blockquote>
<p>The same as above.</p>
<blockquote>
<blockquote>
<blockquote>
<ol start="2">
<li>Float#to_s must be platform independent</li>
</ol>
</blockquote>
<p>double calculation itself is platform dependent.</p>
</blockquote>
<p>Sorry, I should have specified "...on IEEE 754 platforms", which is the case for mgwin32, right?</p>
<blockquote>
<p>Moreover there's non IEEE-754 fp for example VAX.</p>
</blockquote>
<p>We don't support VAX, as you wrote yourself in <a href="/issues/5884">[ruby-core:42077]</a>, so how is this relevant exactly?</p>
</blockquote>
<p>I had written VAX but the main subject of here is x87 FPU.</p>
<p>On 32bit IA (yeah, this is also reproducible on 32bit Linux), program usually calculates floating point numbers with x87 FPU.<br>
x87 FPU stores and calculates floating numbers in 80bit on registers, even if it is stored in 64bit on memory.<br>
Therefore x87's result may differ from modern FPU's result.</p>
<p>For example -1.1505945e-05,<br>
On modern FPU, it is stored/expressed as -0x1.821350a1d1742p-17, and this is converted to -1.1505945E-05 in decimal.<br>
But on x87 FPU this is expressed as -0x1.821350a1d1741800p-17, and converted to -1.1505945000000001E-05 in decimal.<br>
Yeah, this can be avoided by storing it to memory by specifying volatile, but this costs time and make code complex.<br>
On gcc, specifying -ffloat-store or -fexcess-precision=standard (gcc 4.5) is more simple, but this is also slows down.<br>
On modern x86 CPU it has SSE, so specify -msse2 -mfpmath=sse is easy way.</p>
<a name="Note-that-Xeon-Phi-has-x87-and-512bit-SMID-but-doesnt-have-SSE"></a>
<h1 >Note that Xeon Phi has x87 and 512bit SMID, but doesn't have SSE<a href="#Note-that-Xeon-Phi-has-x87-and-512bit-SMID-but-doesnt-have-SSE" class="wiki-anchor">¶</a></h1> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388042013-04-22T12:53:18Zdavid_macmahon (David MacMahon)davidm@astro.berkeley.edu
<ul></ul><p>On Apr 21, 2013, at 7:18 PM, naruse (Yui NARUSE) wrote:</p>
<blockquote>
<p>marcandre (Marc-Andre Lafortune) wrote:</p>
<blockquote>
<p>For any float f, the two following conditions should hold:<br>
(1) f.to_s.to_f == f (round trips)</p>
</blockquote>
<p>Yeah, unless you transfer the result of to_s to another environment.</p>
</blockquote>
<p>Are you saying that round tripping is only valid on "the native architecture's double-precision floating point representation" (quote from Float's RDoc)? That would make sense to me.</p>
<blockquote>
<p>x87 FPU stores and calculates floating numbers in 80bit on registers, even if it is stored in 64bit on memory.</p>
</blockquote>
<p>Does Float on x87 systems use 80-bits to store its value? IOW, is "the native architecture's double-precision floating point representation" 80 bits on x87?Asking (almost) the same thing a third way, what is "sizeof(double)" on a system with an x87 FPU?</p>
<blockquote>
<p>Therefore x87's result may differ from modern FPU's result.</p>
</blockquote>
<p>I agree that the results of floating point operations on x87 may differ from the same operations on modern FPU's given the same input operands due to 80-bit intermediate values on x87, but does this affect the parsing of Float literals?</p>
<p>Do Float constants like EPSILON, MIN, and MAX differ between x87 systems and modern FPUs?</p>
<p>Does "x87" == "non-IEEE-754" and "modern FPU" == "IEEE-754"?</p>
<p>I find this topic fascinating and am just trying to understand the subtle semantics involved here!</p>
<p>Thanks,<br>
Dave</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388052013-04-22T14:23:16Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>2013年4月22日月曜日 David MacMahon <a href="mailto:davidm@astro.berkeley.edu" class="email">davidm@astro.berkeley.edu</a>:</p>
<blockquote>
<p>On Apr 21, 2013, at 7:18 PM, naruse (Yui NARUSE) wrote:</p>
<blockquote>
<p>marcandre (Marc-Andre Lafortune) wrote:</p>
<blockquote>
<p>For any float f, the two following conditions should hold:<br>
(1) f.to_s.to_f == f (round trips)</p>
</blockquote>
<p>Yeah, unless you transfer the result of to_s to another environment.</p>
</blockquote>
<p>Are you saying that round tripping is only valid on "the native<br>
architecture's double-precision floating point representation" (quote from<br>
Float's RDoc)? That would make sense to me.</p>
</blockquote>
<p>Yes.</p>
<blockquote>
<blockquote>
<p>x87 FPU stores and calculates floating numbers in 80bit on registers,<br>
even if it is stored in 64bit on memory.</p>
</blockquote>
<p>Does Float on x87 systems use 80-bits to store its value? IOW, is "the<br>
native architecture's double-precision floating point representation" 80<br>
bits on x87?Asking (almost) the same thing a third way, what is<br>
"sizeof(double)" on a system with an x87 FPU?</p>
<blockquote>
<p>Therefore x87's result may differ from modern FPU's result.</p>
</blockquote>
<p>I agree that the results of floating point operations on x87 may differ<br>
from the same operations on modern FPU's given the same input operands due<br>
to 80-bit intermediate values on x87, but does this affect the parsing of<br>
Float literals?</p>
<p>Do Float constants like EPSILON, MIN, and MAX differ between x87 systems<br>
and modern FPUs?</p>
<p>Does "x87" == "non-IEEE-754" and "modern FPU" == "IEEE-754"?</p>
<p>I find this topic fascinating and am just trying to understand the subtle<br>
semantics involved here!</p>
<p>Thanks,<br>
Dave</p>
</blockquote>
<p>--<br>
NARUSE, Yui <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a></p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388062013-04-22T14:53:12Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>I wrongly sent previous mail.</p>
<p>2013年4月22日月曜日 David MacMahon <a href="mailto:davidm@astro.berkeley.edu" class="email">davidm@astro.berkeley.edu</a>:</p>
<blockquote>
<p>On Apr 21, 2013, at 7:18 PM, naruse (Yui NARUSE) wrote:</p>
<blockquote>
<p>marcandre (Marc-Andre Lafortune) wrote:</p>
<blockquote>
<p>For any float f, the two following conditions should hold:<br>
(1) f.to_s.to_f == f (round trips)</p>
</blockquote>
<p>Yeah, unless you transfer the result of to_s to another environment.</p>
</blockquote>
<p>Are you saying that round tripping is only valid on "the native<br>
architecture's double-precision floating point representation" (quote from<br>
Float's RDoc)? That would make sense to me.</p>
</blockquote>
<p>Yes, only portable on the same architecture.</p>
<blockquote>
<blockquote>
<p>x87 FPU stores and calculates floating numbers in 80bit on registers,<br>
even if it is stored in 64bit on memory.</p>
</blockquote>
<p>Does Float on x87 systems use 80-bits to store its value? IOW, is "the<br>
native architecture's double-precision floating point representation" 80<br>
bits on x87?Asking (almost) the same thing a third way, what is<br>
"sizeof(double)" on a system with an x87 FPU?</p>
</blockquote>
<p>x87 stores value 80bit on registers and arithmetics, 64bit on memory.<br>
So sizeof(double)=8.</p>
<blockquote>
<blockquote>
<p>Therefore x87's result may differ from modern FPU's result.</p>
</blockquote>
<p>I agree that the results of floating point operations on x87 may differ<br>
from the same operations on modern FPU's given the same input operands due<br>
to 80-bit intermediate values on x87, but does this affect the parsing of<br>
Float literals?</p>
</blockquote>
<p>Parsing itself is of course doesn't affect.<br>
Decimal-binary conversion affect it</p>
<blockquote>
<p>Do Float constants like EPSILON, MIN, and MAX differ between x87 systems<br>
and modern FPUs?</p>
</blockquote>
<p>I'll show those constants on my 32bit Linux.</p>
<blockquote>
<p>Does "x87" == "non-IEEE-754" and "modern FPU" == "IEEE-754"?</p>
</blockquote>
<p>I think what you think is correct.<br>
Why I didn't write so is because as far as I understand, x87 complies IEEE<br>
754 standard; the standard allows to store and calculate float64 in 80bit.</p>
<p>--<br>
NARUSE, Yui <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a></p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388082013-04-22T16:05:43ZStudent (Nathan Zook)blogger@pierian-spring.net
<ul></ul><p>The story on x87 is not precisely as you say. Yes, everything is stored in 80 bits. However, you can set precision as well as rounding mode. If the precision is set to DP, the mantissa is rounded to 53 bits, just like double precision. Again, things get a little weird in the denormal range, but this does NOT affect the value in question.</p>
<p>What I don't know is if the standard specifies that floats are stored DP or max platform. Max platform is subject to some oddness when you cross platforms but this does not affect round-tripping, which is the reported issue, which is happing all in a single process.</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388142013-04-22T23:53:16Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>(2013/04/22 12:43), David MacMahon wrote:</p>
<blockquote>
<p>Do Float constants like EPSILON, MIN, and MAX differ between x87 systems and modern FPUs?</p>
</blockquote>
<p>On i486-linux,<br>
DBL_EPSILON: 2.22045e-16<br>
DBL_MAX: 1.79769e+308<br>
DBL_MIN: 2.22507e-308<br>
DBL_MANT_DIG : 53<br>
DBL_EXP_MAX: 1024,<br>
DBL_EXP_MIN: -1021</p>
<p>They are same as x64.</p>
<p>--<br>
NARUSE, Yui <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a></p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388212013-04-23T11:15:37Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>I guess this is a compiler specific issue.</p>
<p>I tested some cases with different compilers with Ruby 1.9.3-p392 on the same machine.<br>
gcc 4.5.2 built version(rubyinstaller version) shows not disired result.<br>
But gcc 4.7.2 and MSVC v16.0 built version shows a correct result.</p>
<p>C:\work\ruby-1.9.3-p392-mg5>.\miniruby -ve 'a=-1.1505945E-5;puts(a,"%0.20g"%a)'<br>
ruby 1.9.3p392 (2013-02-22 revision 39386) [i386-mingw32]<br>
-1.1505945000000001e-05<br>
-1.1505945000000000847e-05</p>
<p>C:\work\ruby-1.9.3-p392-mg7>.\miniruby -ve 'a=-1.1505945E-5;puts(a,"%0.20g"%a)'<br>
ruby 1.9.3p392 (2013-02-22 revision 39386) [i386-mingw32]<br>
-1.1505945e-05<br>
-1.1505944999999999153e-05</p>
<p>C:\work\ruby-1.9.3-p392-ms>.\miniruby -ve 'a=-1.1505945E-5;puts(a,"%0.20g"%a)'<br>
ruby 1.9.3p392 (2013-02-22 revision 39386) [i386-mswin32_100]<br>
-1.1505945e-05<br>
-1.1505944999999999153e-05</p>
<p>I found the main cause is the different result of rounded quotient operation.<br>
Here is the test case.</p>
<pre><code>C:\work>type foo.c
#include <stdio.h>
void main() {
double a = 11505945.0;
double b = 1000000000000.0;
a /= b;
printf("a = %0.20g\n",a);
}
C:\work>gcc --version
gcc (tdm-1) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
C:\work>gcc foo.c -o foo
C:\work>foo
a = 1.1505945000000001e-005
C:\work>gcc --version
gcc (rubenvb-4.7.2-release) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
C:\work>gcc foo.c -o foo
C:\work>foo
a = 1.1505944999999999e-005
C:\work>cl foo.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
foo.c
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:foo.exe
foo.obj
C:\work>foo
a = 1.1505944999999999e-005
</code></pre> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388612013-04-24T16:05:46Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>I found the issue is due to the difference of the floating point precision.</p>
<p>Here is a patch for this issue:</p>
<pre><code>diff --git a/numeric.c b/numeric.c.new
index 97ba104..c548c0f 100644
--- a/numeric.c
+++ b/numeric.c.new
@@ -3767,6 +3767,9 @@ Init_Numeric(void)
_control87(MCW_EM, MCW_EM);
_control87(_control87(0,0),0x1FFF);
#endif
+#if defined(__MINGW32__)
+ _control87(_PC_53, _MCW_PC);
+#endif
id_coerce = rb_intern("coerce");
id_to_i = rb_intern("to_i");
id_eq = rb_intern("==");
</code></pre> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388722013-04-25T02:23:15Zdavid_macmahon (David MacMahon)davidm@astro.berkeley.edu
<ul></ul><p>Nice work tracking this down!</p>
<p>I don't understand how it fixes the compiler specific aspect of the problem you found where gcc 4.5.2 on MinGW had the problem but gcc 4.7.2 on MinGW did not. Does gcc 4.7.2 on MinGW already automatically do whatever "_control87(_PC_53, _MCW_PC)" does, but gcc 4,5,2 on MinGW does not automatically do it so it needs to be done explicitly?</p>
<p>Is the <strong>MINGW32</strong> macro enough of a check? I wonder if it could enable the _control87 call on system where it is not present.</p>
<p>Dave</p>
<p>On Apr 24, 2013, at 12:05 AM, phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by phasis68 (Heesob Park).</p>
<p>I found the issue is due to the difference of the floating point precision.</p>
<p>Here is a patch for this issue:</p>
<p>diff --git a/numeric.c b/numeric.c.new<br>
index 97ba104..c548c0f 100644<br>
--- a/numeric.c<br>
+++ b/numeric.c.new<br>
@@ -3767,6 +3767,9 @@ Init_Numeric(void)<br>
_control87(MCW_EM, MCW_EM);<br>
_control87(_control87(0,0),0x1FFF);<br>
#endif<br>
+#if defined(<strong>MINGW32</strong>)</p>
<ul>
<li>_control87(_PC_53, _MCW_PC);<br>
+#endif<br>
id_coerce = rb_intern("coerce");<br>
id_to_i = rb_intern("to_i");<br>
id_eq = rb_intern("==");</li>
</ul>
<hr>
<p>Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a>: Minor error in float parsing<br>
<a href="https://bugs.ruby-lang.org/issues/8299#change-38861" class="external">https://bugs.ruby-lang.org/issues/8299#change-38861</a></p>
<p>Author: bobjalex (Bob Alexander)<br>
Status: Open<br>
Priority: Normal<br>
Assignee:<br>
Category:<br>
Target version:<br>
ruby -v: trunk<br>
Backport:</p>
<p>I encountered a float that either parses [slightly] differently (or converts to string differently) in Ruby than it does in Python or Java. This looks like a Ruby bug since the result "looks" incorrect.</p>
<p>It is easily reproduced by entering the magic number (-1.1505945E-5) into irb. It behaves the same in 2.0 and 1.9. I'm using Windows.</p>
<p>Below is an irb session that demonstrates. Also included are JRuby and Python trials that show better behavior.</p>
<p>This issue is not causing me any problems, but just in case someone there is interested in looking into it...</p>
<p>Bob</p>
<blockquote>
<p>ruby -v<br>
ruby 2.0.0p0 (2013-02-24) [i386-mingw32]</p>
</blockquote>
<blockquote>
<p>irb<br>
irb(main):001:0> RUBY_VERSION<br>
=> "2.0.0"<br>
irb(main):002:0> -1.1505945E-5<br>
=> -1.1505945000000001e-05</p>
</blockquote>
<blockquote>
<p>ruby19 -v<br>
ruby 1.9.3p392 (2013-02-22) [i386-mingw32]</p>
</blockquote>
<blockquote>
<p>irb19<br>
irb(main):001:0> RUBY_VERSION<br>
=> "1.9.3"<br>
irb(main):002:0> -1.1505945E-5<br>
=> -1.1505945000000001e-05<br>
irb(main):002:0></p>
</blockquote>
<blockquote>
<p>jirb<br>
irb(main):001:0> -1.1505945E-5<br>
=> -1.1505945e-05</p>
</blockquote>
<blockquote>
<p>python<br>
Python 2.7.4rc1 (default, Mar 24 2013, 14:34:32) [MSC v.1500 32 bit (Intel)] on<br>
win32<br>
Type "help", "copyright", "credits" or "license" for more information.</p>
<blockquote>
<blockquote>
<p>-1.1505945E-5<br>
-1.1505945e-05<br>
repr(-1.1505945E-5)<br>
'-1.1505945e-05'</p>
</blockquote>
</blockquote>
</blockquote>
<p>--<br>
<a href="http://bugs.ruby-lang.org/" class="external">http://bugs.ruby-lang.org/</a></p>
</blockquote> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388752013-04-25T06:49:18Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>I found the issue is due to the difference of the floating point precision.</p>
<p>Here is a patch for this issue:</p>
<pre><code>diff --git a/numeric.c b/numeric.c.new
index 97ba104..c548c0f 100644
--- a/numeric.c
+++ b/numeric.c.new
@@ -3767,6 +3767,9 @@ Init_Numeric(void)
_control87(MCW_EM, MCW_EM);
_control87(_control87(0,0),0x1FFF);
#endif
+#if defined(__MINGW32__)
+ _control87(_PC_53, _MCW_PC);
+#endif
id_coerce = rb_intern("coerce");
id_to_i = rb_intern("to_i");
id_eq = rb_intern("==");
</code></pre>
</blockquote>
<p>It specify fraction as 53 bit (other IEEE 754 FPU's 52 bit with economized form), but its internal exponent is still 15 bit.<br>
For example following result should be still different (I don't tested on mingw32).</p>
<p>[0x0008008000000000,0x3ff0000000000001].pack("Q2").unpack("d2").inject(&:*)</p>
<p>Therefore use SSE2 rather than such workaround.</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388782013-04-25T11:23:17Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>2013/4/25 David MacMahon <a href="mailto:davidm@astro.berkeley.edu" class="email">davidm@astro.berkeley.edu</a></p>
<blockquote>
<p>Nice work tracking this down!</p>
<p>I don't understand how it fixes the compiler specific aspect of the<br>
problem you found where gcc 4.5.2 on MinGW had the problem but gcc 4.7.2 on<br>
MinGW did not. Does gcc 4.7.2 on MinGW already automatically do whatever<br>
"_control87(_PC_53, _MCW_PC)" does, but gcc 4,5,2 on MinGW does not<br>
automatically do it so it needs to be done explicitly?</p>
</blockquote>
<p>The console application built with mingw32 compiler calls _fpreset<br>
funciton at startup.<br>
The _fpreset function is defined in MSVCRT.dll which set FP default<br>
precision to 53 bit mantissa.</p>
<p>But in mingwrt-3.18 library which bundled in mingw32 4.7.2 redefined<br>
_fpreset function to change FP default precision from 53 to 64-bit<br>
mantissa.<br>
Actually, the "_control87(_PC_53, _MCW_PC)" means lowering precision<br>
from 64 to 53-bit mantissa.</p>
<p>BTW, why we should consider FP precision?<br>
When converting string value to double value, ruby calls ruby_strtod<br>
function instead of native strtod function.<br>
The ruby_strtod function is based on David M. Gay's netlib library<br>
which requires double-precision (53-bit) rounding precision.</p>
<blockquote>
<p>Is the <strong>MINGW32</strong> macro enough of a check? I wonder if it could enable<br>
the _control87 call on system where it is not present.</p>
</blockquote>
<p>Ruby 1.9.x requires Windows 2000 or later OS which requires Pentium CPU.<br>
And most x86 processors since the Intel 80486 have had x87<br>
instructions implemented in the main CPU.<br>
I cannot imagine a system with Windows 2000 and not present x87 instructions.</p>
<p>Regards,<br>
Park Heesob</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388792013-04-25T11:23:18Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by naruse (Yui NARUSE).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>I found the issue is due to the difference of the floating point precision.</p>
<p>Here is a patch for this issue:</p>
<pre><code>diff --git a/numeric.c b/numeric.c.new
index 97ba104..c548c0f 100644
--- a/numeric.c
+++ b/numeric.c.new
@@ -3767,6 +3767,9 @@ Init_Numeric(void)
_control87(MCW_EM, MCW_EM);
_control87(_control87(0,0),0x1FFF);
#endif
+#if defined(__MINGW32__)
+ _control87(_PC_53, _MCW_PC);
+#endif
id_coerce = rb_intern("coerce");
id_to_i = rb_intern("to_i");
id_eq = rb_intern("==");
</code></pre>
</blockquote>
<p>It specify fraction as 53 bit (other IEEE 754 FPU's 52 bit with economized form), but its internal exponent is still 15 bit.<br>
For example following result should be still different (I don't tested on mingw32).</p>
<p>[0x0008008000000000,0x3ff0000000000001].pack("Q2").unpack("d2").inject(&:*)</p>
<p>Therefore use SSE2 rather than such workaround.</p>
</blockquote>
<p>I'm not sure why you think SSE2 can fix this issue.</p>
<p>The ruby_strtod function used in converting string value to double<br>
value requires double-precision (53-bit) rounding precision but<br>
mingw32 gcc 4.5.2 have default 64-bit precision which higher than<br>
other compilers.</p>
<p>So the patch lowers precision from 64 bit to 53 bit.</p>
<p>Regards,<br>
Park Heesob</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388802013-04-25T11:41:27Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Therefore use SSE2 rather than such workaround.</p>
</blockquote>
<p>I'm not sure why you think SSE2 can fix this issue.</p>
<p>The ruby_strtod function used in converting string value to double<br>
value requires double-precision (53-bit) rounding precision but<br>
mingw32 gcc 4.5.2 have default 64-bit precision which higher than<br>
other compilers.</p>
<p>So the patch lowers precision from 64 bit to 53 bit.</p>
</blockquote>
<p>double arithmetics with SSE2 is double-precision.<br>
see also gcc's -mfpmath=sse option<br>
<a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959" class="external">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959</a></p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388922013-04-25T13:53:19Zdavid_macmahon (David MacMahon)davidm@astro.berkeley.edu
<ul></ul><p>On Apr 24, 2013, at 7:03 PM, Heesob Park wrote:</p>
<blockquote>
<p>2013/4/25 David MacMahon <a href="mailto:davidm@astro.berkeley.edu" class="email">davidm@astro.berkeley.edu</a></p>
<blockquote>
<p>Nice work tracking this down!</p>
<p>I don't understand how it fixes the compiler specific aspect of the<br>
problem you found where gcc 4.5.2 on MinGW had the problem but gcc 4.7.2 on<br>
MinGW did not. Does gcc 4.7.2 on MinGW already automatically do whatever<br>
"_control87(_PC_53, _MCW_PC)" does, but gcc 4,5,2 on MinGW does not<br>
automatically do it so it needs to be done explicitly?</p>
</blockquote>
<p>The console application built with mingw32 compiler calls _fpreset<br>
funciton at startup.<br>
The _fpreset function is defined in MSVCRT.dll which set FP default<br>
precision to 53 bit mantissa.</p>
<p>But in mingwrt-3.18 library which bundled in mingw32 4.7.2 redefined<br>
_fpreset function to change FP default precision from 53 to 64-bit<br>
mantissa.<br>
Actually, the "_control87(_PC_53, _MCW_PC)" means lowering precision<br>
from 64 to 53-bit mantissa.</p>
</blockquote>
<p>Thanks for the information, but I'm still confused. The above sounds like gcc 4.7.2 uses a higher precision (64 bit mantissa) than strtod expects (53 bit mantissa), yet in an earlier message you wrote:</p>
<blockquote>
<p>gcc 4.5.2 built version(rubyinstaller version) shows not disired result.<br>
But gcc 4.7.2 and MSVC v16.0 built version shows a correct result.</p>
</blockquote>
<p>Not a big problem, I'm just trying to understand things. Am I misreading/misinterpreting things?</p>
<blockquote>
<p>BTW, why we should consider FP precision?<br>
When converting string value to double value, ruby calls ruby_strtod<br>
function instead of native strtod function.<br>
The ruby_strtod function is based on David M. Gay's netlib library<br>
which requires double-precision (53-bit) rounding precision.</p>
</blockquote>
<p>This raises the question of whether Ruby really supports "the native architecture's double-precision floating point representation" as described on Float's RDoc. Does strtod work properly on systems that use something other than IEEE 754 binary64 (e.g. VAX)?</p>
<blockquote>
<blockquote>
<p>Is the <strong>MINGW32</strong> macro enough of a check? I wonder if it could enable<br>
the _control87 call on system where it is not present.</p>
</blockquote>
<p>Ruby 1.9.x requires Windows 2000 or later OS which requires Pentium CPU.<br>
And most x86 processors since the Intel 80486 have had x87<br>
instructions implemented in the main CPU.<br>
I cannot imagine a system with Windows 2000 and not present x87 instructions.</p>
</blockquote>
<p>There is Windows RT...</p>
<p><a href="http://en.wikipedia.org/wiki/Windows_RT" class="external">http://en.wikipedia.org/wiki/Windows_RT</a></p>
<p>...but I don't know whether Ruby runs on it. :-)</p>
<p>Dave</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388952013-04-25T14:53:18Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>2013/4/25 David MacMahon <a href="mailto:davidm@astro.berkeley.edu" class="email">davidm@astro.berkeley.edu</a>:</p>
<blockquote>
<p>On Apr 24, 2013, at 7:03 PM, Heesob Park wrote:</p>
<blockquote>
<p>2013/4/25 David MacMahon <a href="mailto:davidm@astro.berkeley.edu" class="email">davidm@astro.berkeley.edu</a></p>
<blockquote>
<p>Nice work tracking this down!</p>
<p>I don't understand how it fixes the compiler specific aspect of the<br>
problem you found where gcc 4.5.2 on MinGW had the problem but gcc 4.7.2 on<br>
MinGW did not. Does gcc 4.7.2 on MinGW already automatically do whatever<br>
"_control87(_PC_53, _MCW_PC)" does, but gcc 4,5,2 on MinGW does not<br>
automatically do it so it needs to be done explicitly?</p>
</blockquote>
<p>The console application built with mingw32 compiler calls _fpreset<br>
funciton at startup.<br>
The _fpreset function is defined in MSVCRT.dll which set FP default<br>
precision to 53 bit mantissa.</p>
<p>But in mingwrt-3.18 library which bundled in mingw32 4.7.2 redefined<br>
_fpreset function to change FP default precision from 53 to 64-bit<br>
mantissa.<br>
Actually, the "_control87(_PC_53, _MCW_PC)" means lowering precision<br>
from 64 to 53-bit mantissa.</p>
</blockquote>
<p>Thanks for the information, but I'm still confused. The above sounds like gcc 4.7.2 uses a higher precision (64 bit mantissa) than strtod expects (53 bit mantissa), yet in an earlier message you wrote:</p>
</blockquote>
<p>The higher precision produce the undesired result in the magic number<br>
(-1.1505945E-5).<br>
-1.1505945000000001e-05 instead of -1.1505945e-05.</p>
<blockquote>
<blockquote>
<p>gcc 4.5.2 built version(rubyinstaller version) shows not disired result.<br>
But gcc 4.7.2 and MSVC v16.0 built version shows a correct result.</p>
</blockquote>
<p>Not a big problem, I'm just trying to understand things. Am I misreading/misinterpreting things?</p>
</blockquote>
<p>I just mentioned the issue is occurred on mingw32 gcc 4.5.2 compiler<br>
due to the excess precision.</p>
<blockquote>
<blockquote>
<p>BTW, why we should consider FP precision?<br>
When converting string value to double value, ruby calls ruby_strtod<br>
function instead of native strtod function.<br>
The ruby_strtod function is based on David M. Gay's netlib library<br>
which requires double-precision (53-bit) rounding precision.</p>
</blockquote>
<p>This raises the question of whether Ruby really supports "the native architecture's double-precision floating point representation" as described on Float's RDoc. Does strtod work properly on systems that use something other than IEEE 754 binary64 (e.g. VAX)?</p>
</blockquote>
<p>I have no idea why ruby call David M. Gay's strtod instead of native<br>
strtod funciton.</p>
<blockquote>
<blockquote>
<blockquote>
<p>Is the <strong>MINGW32</strong> macro enough of a check? I wonder if it could enable<br>
the _control87 call on system where it is not present.</p>
</blockquote>
<p>Ruby 1.9.x requires Windows 2000 or later OS which requires Pentium CPU.<br>
And most x86 processors since the Intel 80486 have had x87<br>
instructions implemented in the main CPU.<br>
I cannot imagine a system with Windows 2000 and not present x87 instructions.</p>
</blockquote>
<p>There is Windows RT...</p>
<p><a href="http://en.wikipedia.org/wiki/Windows_RT" class="external">http://en.wikipedia.org/wiki/Windows_RT</a></p>
<p>...but I don't know whether Ruby runs on it. :-)</p>
</blockquote>
<p>The patch can be more strict like this:<br>
#if defined(<strong>MINGW32</strong>) && defined(_M_IX86)<br>
_control87(_PC_53, _MCW_PC);<br>
#endif</p>
<p>Regards,<br>
Park Heesob</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=388962013-04-25T14:53:18Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by naruse (Yui NARUSE).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Therefore use SSE2 rather than such workaround.</p>
</blockquote>
<p>I'm not sure why you think SSE2 can fix this issue.</p>
<p>The ruby_strtod function used in converting string value to double<br>
value requires double-precision (53-bit) rounding precision but<br>
mingw32 gcc 4.5.2 have default 64-bit precision which higher than<br>
other compilers.</p>
<p>So the patch lowers precision from 64 bit to 53 bit.</p>
</blockquote>
<p>double arithmetics with SSE2 is double-precision.<br>
see also gcc's -mfpmath=sse option<br>
<a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959" class="external">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959</a></p>
</blockquote>
<p>I agree that SSE2 is the better solution for modern OS and modern compiler.</p>
<p>But SSE2 has more restrictions than x87.<br>
SSE2 is not supported on the following environment.<br>
Microsoft Visual C++ Compiler prior to Visual Studio .NET 2003.<br>
AMD CPUs prior to Athlon 64, including all Socket A-based CPUs<br>
Intel CPUs prior to Pentium 4</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=389002013-04-25T17:12:16Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by naruse (Yui NARUSE).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Therefore use SSE2 rather than such workaround.</p>
</blockquote>
<p>I'm not sure why you think SSE2 can fix this issue.</p>
<p>The ruby_strtod function used in converting string value to double<br>
value requires double-precision (53-bit) rounding precision but<br>
mingw32 gcc 4.5.2 have default 64-bit precision which higher than<br>
other compilers.</p>
<p>So the patch lowers precision from 64 bit to 53 bit.</p>
</blockquote>
<p>double arithmetics with SSE2 is double-precision.<br>
see also gcc's -mfpmath=sse option<br>
<a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959" class="external">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959</a></p>
</blockquote>
<p>I agree that SSE2 is the better solution for modern OS and modern compiler.</p>
<p>But SSE2 has more restrictions than x87.<br>
SSE2 is not supported on the following environment.<br>
Microsoft Visual C++ Compiler prior to Visual Studio .NET 2003.</p>
</blockquote>
<p>Use newer compiler.</p>
<blockquote>
<pre><code>AMD CPUs prior to Athlon 64, including all Socket A-based CPUs
Intel CPUs prior to Pentium 4
</code></pre>
</blockquote>
<p>Use -mfpmath=sse,387.<br>
As I wrote before, if you want to get the same result with x87 FPU _control87(_PC_53, _MCW_PC) is not sufficient.<br>
It needs to handle 15 bit exponent.<br>
If you want to do that, it is as hard as implementing strictfp of Java on x87.<br>
see also <a href="http://math.nist.gov/javanumerics/reports/jgfnwg-01.html" class="external">http://math.nist.gov/javanumerics/reports/jgfnwg-01.html</a><br>
<a href="http://www.shudo.net/java-grandprix99/strictfp/#JGNWG98-2" class="external">http://www.shudo.net/java-grandprix99/strictfp/#JGNWG98-2</a> (Japanese)</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=389052013-04-25T17:53:25Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by naruse (Yui NARUSE).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by naruse (Yui NARUSE).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Therefore use SSE2 rather than such workaround.</p>
</blockquote>
<p>I'm not sure why you think SSE2 can fix this issue.</p>
<p>The ruby_strtod function used in converting string value to double<br>
value requires double-precision (53-bit) rounding precision but<br>
mingw32 gcc 4.5.2 have default 64-bit precision which higher than<br>
other compilers.</p>
<p>So the patch lowers precision from 64 bit to 53 bit.</p>
</blockquote>
<p>double arithmetics with SSE2 is double-precision.<br>
see also gcc's -mfpmath=sse option<br>
<a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959" class="external">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959</a></p>
</blockquote>
<p>I agree that SSE2 is the better solution for modern OS and modern compiler.</p>
<p>But SSE2 has more restrictions than x87.<br>
SSE2 is not supported on the following environment.<br>
Microsoft Visual C++ Compiler prior to Visual Studio .NET 2003.</p>
</blockquote>
<p>Use newer compiler.<br>
The requirement in win32/README.win32 need to be modified.</p>
</blockquote>
<blockquote>
<blockquote>
<pre><code>AMD CPUs prior to Athlon 64, including all Socket A-based CPUs
Intel CPUs prior to Pentium 4
</code></pre>
</blockquote>
<p>Use -mfpmath=sse,387.<br>
As I wrote before, if you want to get the same result with x87 FPU _control87(_PC_53, _MCW_PC) is not sufficient.<br>
It needs to handle 15 bit exponent.</p>
</blockquote>
<p>I don't want the same result with SSE2 and x87 FPU.<br>
The 15 bit exponent is not a matter of this issue.<br>
The point is that ruby_strtod function requires 53-bit precision and<br>
mingw32 4.5.2 compiler is 64-bit precision unlike other windows<br>
compiler which is 53-bit precision.<br>
I confirmed that _control87(_PC_53, _MCW_PC) patch works fine with<br>
ruby 1.9.3 mingw32 gcc 4.5.2 version.</p>
<blockquote>
<p>If you want to do that, it is as hard as implementing strictfp of Java on x87.<br>
see also <a href="http://math.nist.gov/javanumerics/reports/jgfnwg-01.html" class="external">http://math.nist.gov/javanumerics/reports/jgfnwg-01.html</a><br>
<a href="http://www.shudo.net/java-grandprix99/strictfp/#JGNWG98-2" class="external">http://www.shudo.net/java-grandprix99/strictfp/#JGNWG98-2</a> (Japanese)</p>
</blockquote>
<p>You've gone too far from this issue.<br>
The issuer wants the correct value of strtod function on the ruby<br>
1.9.3 mingw32 version.<br>
My patch is for mingw32 gcc compiler only.</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=389152013-04-26T07:35:44Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Category</strong> set to <i>platform/mingw</i></li><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>nobu (Nobuyoshi Nakada)</i></li></ul><p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by naruse (Yui NARUSE).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Minor error in float parsing (Closed)" href="https://bugs.ruby-lang.org/issues/8299">#8299</a> has been updated by naruse (Yui NARUSE).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>2013/4/25 naruse (Yui NARUSE) <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a>:</p>
<blockquote>
<p>Therefore use SSE2 rather than such workaround.</p>
</blockquote>
<p>I'm not sure why you think SSE2 can fix this issue.</p>
<p>The ruby_strtod function used in converting string value to double<br>
value requires double-precision (53-bit) rounding precision but<br>
mingw32 gcc 4.5.2 have default 64-bit precision which higher than<br>
other compilers.</p>
<p>So the patch lowers precision from 64 bit to 53 bit.</p>
</blockquote>
<p>double arithmetics with SSE2 is double-precision.<br>
see also gcc's -mfpmath=sse option<br>
<a href="http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959" class="external">http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/i386-and-x86_002d64-Options.html#index-march-959</a></p>
</blockquote>
<p>I agree that SSE2 is the better solution for modern OS and modern compiler.</p>
<p>But SSE2 has more restrictions than x87.<br>
SSE2 is not supported on the following environment.<br>
Microsoft Visual C++ Compiler prior to Visual Studio .NET 2003.</p>
</blockquote>
<p>Use newer compiler.<br>
The requirement in win32/README.win32 need to be modified.</p>
</blockquote>
</blockquote>
<p>There's already "strongly recommended VC++ 10 or later".<br>
Note that VC++2003 or later has /fp:precise and it is default</p>
<blockquote>
<blockquote>
<blockquote>
<pre><code>AMD CPUs prior to Athlon 64, including all Socket A-based CPUs
Intel CPUs prior to Pentium 4
</code></pre>
</blockquote>
<p>Use -mfpmath=sse,387.<br>
As I wrote before, if you want to get the same result with x87 FPU _control87(_PC_53, _MCW_PC) is not sufficient.<br>
It needs to handle 15 bit exponent.</p>
</blockquote>
<p>I don't want the same result with SSE2 and x87 FPU.<br>
The 15 bit exponent is not a matter of this issue.<br>
The point is that ruby_strtod function requires 53-bit precision and<br>
mingw32 4.5.2 compiler is 64-bit precision unlike other windows<br>
compiler which is 53-bit precision.<br>
I confirmed that _control87(_PC_53, _MCW_PC) patch works fine with<br>
ruby 1.9.3 mingw32 gcc 4.5.2 version.</p>
</blockquote>
<p>Your patch changes global state.<br>
Change global or apply it to ruby_strtod is up to nobu, the mingw port maintainer.</p>
<blockquote>
<blockquote>
<p>If you want to do that, it is as hard as implementing strictfp of Java on x87.<br>
see also <a href="http://math.nist.gov/javanumerics/reports/jgfnwg-01.html" class="external">http://math.nist.gov/javanumerics/reports/jgfnwg-01.html</a><br>
<a href="http://www.shudo.net/java-grandprix99/strictfp/#JGNWG98-2" class="external">http://www.shudo.net/java-grandprix99/strictfp/#JGNWG98-2</a> (Japanese)</p>
</blockquote>
<p>You've gone too far from this issue.<br>
The issuer wants the correct value of strtod function on the ruby<br>
1.9.3 mingw32 version.<br>
My patch is for mingw32 gcc compiler only.</p>
</blockquote>
<p>Hmm, up to nobu.</p> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=1052942023-11-13T18:58:59ZJesseJohnson (Jesse Johnson)
<ul></ul><p>I'm not able to replicate this in Ruby 2.6 or Ruby 3.2. Has this been fixed in the relevant compilers? If so can this bug be closed?</p>
<pre><code>irb(main):001:0> RUBY_VERSION
=> "2.6.10"
irb(main):002:0> -1.1505945E-5
=> -1.1505945e-05
</code></pre>
<pre><code>irb(main):001> RUBY_VERSION
=> "3.2.2"
irb(main):002> -1.1505945E-5
=> -1.1505945e-05
</code></pre> Ruby master - Bug #8299: Minor error in float parsinghttps://bugs.ruby-lang.org/issues/8299?journal_id=1054312023-11-28T09:55:59Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>hdtoa has the rounding logic, but it doesn't work well on x87, but no one use x87 now. This issue is resolved.</p>