MinGW and MSVCRT Conflict Causes Floating-Point Value Corruption
jones_supa writes: If you are working on a C++ program where you need very accurate floating point numbers, you might have decided to use long double data type for the extra precision. After a few calculations, you happen to print your number. To your shock, instead of the number being 123.456789, it is printed out as -6.518427 × 10^264 (or 2.745563 depending on your computer). This is actually a bug in some versions of MinGW g++ 4.8.1 (MinGW is a port of GNU programming tools for Windows). Microsoft's C++ runtime library reserves 80 bits for double and long double. When MinGW uses the Microsoft DLL to print out the value, the number is interpreted as using only 64 bits. This discrepancy causes garbage results to be output.
The title implies that the floating point value becomes corrupt. Without looking into it, it sounds like the value does not become corrupt but rather is just not output correctly. The underlying value is still intact.
The sage of Wikipedia states
So the program implementation assumed a behavior that was not guaranteed, and was burned when it used an outside library which was specification compliant but not in the same way as that particular implementation.
A poor workman blames his tools. And in this case I'm not referring to MinGW, which is admirably neutral in its reporting.
This is well known. I had a bug in a tree class due to this. The key stored in the instance was 64 bit, but the compare class evaluated and compared it in 80 bits. One of the most difficult bugs I ever encountered. Highly recursive calls to the compare function failing once in about a billion calls... But that was almost 10 or 12 years ago.
But one thing. GCC handled the truncations correctly. It allows the 80 bit evaluations turned off by compiler options. I don't mix GCC with msvcrt so I am not sure how old / new this is. My 80 bit adventure was in Linux on Intel chips.
sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
It's an ABI mismatch, and the summary is nonsense, saying almost the exact opposite of TFA (which I actually read, because the summary is obvious nonsense). The issue is that the Windows ABI defines long double as being a 64-bit floating point value (which is fine, because the only requirement for long double is that it have no less precision than double. If you're using it and expecting some guaranteed precision for vaguely portable code then you're an idiot). For some reason, MinGW (which aims to be ABI-compatible with MS, at least for C libraries) uses 80-bit x87 values for long double, so you get truncation. I forget the exact calling conventions for Windows i386, but I believe that in some cases this will be silently hidden, as the value will be passed in x87 register and so be transparently extended to 80 bits in the caller and truncated in the callee anyway. It's only if it's passed on the stack (or indirectly via a pointer) that it's a problem.
It's not obvious which definition of long double is better. On modern x86, you'll use SSE for 32- and 64-bit values, and may lose precision moving between x87 and SSE registers. You also get worse IEEE compliance out of the x87 unit, which may matter more than the extra 16 bits of precision. 80-bit floats are not available on any platform other than x86 (128-bit is more common, though PowerPC has its own special non-IEEE version of these and on some other platforms they're entirely done in software), so they're a bad choice if you want portable code that generates the same output on different platforms.
I am TheRaven on Soylent News
... this is better than posting stories about SourceForge getting caught highjacking the dev accounts of major OSS projects I guess.
64 bits should be enough for anybody
Also earlier versions of MinGW do not have the problem. It's a regression.
Which means it's a 100% windows bug
No. The MinGW version of GCC allowed to compile programs against the Microsoft C++ runtime library, but the compiler created code which did not follow the spec of the Microsoft library. There really isn't anything to blame about Windows here.
But once I've debugged my software and uploaded it to SourceForge can I be sure it won't have an advertising spyware package added to the installer by DICE?
It's the other way around. long double is 80 bits long and most decidedly does fit into 16 bytes, which is does so presumably for alignment purposes.
systemd is Roko's Basilisk.
SourceForge, the code repository site owned by Slashdot Media, has apparently seized control of the account hosting GIMP for Windows on the service, according to e-mails and discussions amongst members of the GIMP community—locking out GIMP's lead Windows developer. And now anyone downloading the Windows version of the open source image editing tool from SourceForge gets the software wrapped in an installer replete with advertisements.
http://arstechnica.com/informa...
The GIMP developers aren't happy at all about this. They say that Sourceforge impersonated the GIMP developers, and abused the trademarks owned by the GNOME foundation.
https://mail.gnome.org/archive...
x87 can produce IEEE 754 compliant results if the compiler either sets the correct rounding mode before each operation OR if it stores and reloads the results of each operation into memory (forcing the correct rounding).
However, both are expensive to do, performance wise, and no compiler does so by default.
Instead, x87 is normally used a way which is not IEEE 754 compliant, although it's actually a bit more accurate: internally, everything is done with 80 bit precision.
This results from the fact the x87 unit actually predates the final version of the IEEE 754 standard.
The IEEE 754 standard only covers a few operations: add, subtract, multiply, divide, FMA,
The transcendals (sin, cos, tag, exp, pow, etc) functions have never been part of the IEEE 754. Historically, most x87 FPUs have had errors larger than 1 ulp, at least for some part of the range.it
If I am not mistaken, only the AMD K5 FPU actually provided errors of less than 1 ulp for the entire range of inputs. And please, take this with a large grain of salt.