MinGW and MSVCRT Conflict Causes Floating-Point Value Corruption 98
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.
news (Score:1)
Compiler bugs are news ?
Re: (Score:2)
News is what you click on
You don't have to click on it. It just shows up on the front page.
Well, from Dice's perspective... (Score:5, Informative)
... this is better than posting stories about SourceForge getting caught highjacking the dev accounts of major OSS projects I guess.
Re: (Score:1)
Yes, they did on a Windows version of Gimp. They claimed the account had been abandoned, and they were making it more useful for users.
Re: Well, from Dice's perspective... (Score:5, Informative)
Re: (Score:2)
No it's not a clear violation of the GPL. Go read the GPL text itself. The GPL refers to the binary itself, not the installer. The binary itself, unmodified (or modified with source code), with a clear link to the source can be distributed easily, wrapped in whatever proprietary installer you want. The GPL is only transmitted through direct linkage. What SF did was certainly unethical, but it wasn't illegal.
Re: (Score:2)
The issue was the malware wrapper. It abuses the rep of the developers as bait to get people to install the adware.
Re: (Score:2)
Why don't the GIMP maintainers just accept to take back control, then "update" the project by removing all the source code files and replacing them with funny cat pictures?
Re: Surprised? (Score:2)
And he's runnig this all through bootcamp on a macbook air.
Re: (Score:1)
FTA
This is actually a bug in some versions of MinGW g++ 4.8.1.
Re: (Score:1)
The fine article actually pins it on gcc, and mentions that the later MinGW doesn't have this problem, so the whole /. article isn't very interesting ...
Re: (Score:3)
Re: Surprised? (Score:5, Informative)
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.
Re:Surprised? (Score:5, Informative)
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.
Re: (Score:2)
saying almost the exact opposite of TFA (which I actually read, because the summary is obvious nonsense).
Oops, indeed... 80-bit for GCC, 64-bit for MSVCRT. I stand corrected.
Re: (Score:2)
But the article clearly puts the blame on MinGW.
Not really...
He even gives links to the patch.
... and this patch makes MinGW use its own implementation of printf (and family...), rather than trusting Microsoft's buggy version.
Re: (Score:1)
You also get worse IEEE compliance out of the x87 unit, which may matter more than the extra 16 bits of precision.
As far as I am aware, the x87 was fully IEEE compliant so long as you asked for 64-bit (or 32-bit) rounding after every operation (which was implicit if you write all operations back to memory) until Intel decided that precision didnt matter as much as benchmark performance. It was about mid-2014 that Intels newest precision issues made the frontpage of slashdot (Where Intel Processors Fail At Math (Again) [slashdot.org]
Re: (Score:3)
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 uni
Re: (Score:1)
The 80-bit long double is also available on the 68881, 68882 coprocessors and later 68K family members that incorporate the FPU. The Itanium also supports the 80-bit format.
But yeah... those aren't particularly common these days.
Re: (Score:3)
The sage of Wikipedia states [wikipedia.org]
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 particula
Re: (Score:2)
C standard is not the end-all be-all, there are all specifications that define the details of ABI for a particular architecture and platform. In case of VC++, it is well-documented that long double is the same as double, so any compiler that has an explicit stated goal of being ABI-compatible must respect that.
Re: (Score:1)
You used GNU's compiler (on Windows) for floating point maths and got the wrong answer? Surely not!
FTFY.
Bad title. (Score:2)
Re: (Score:3)
If you wanted to rely on that output, say write to a csv file, the data in the csv file is then effectively corrupt.
Could be worst (Score:1, Offtopic)
Try doing the same thing on an original Pentium [wikipedia.org].
Re: (Score:1)
Sorry, non-native english.
Re: (Score:1)
Derp. Not only does your comment add nothing to the discussion, but you can't even use "could be worse" correctly.
Wow, a self-referencing recursive comment!
the 80 bit issue is well known (Score:5, Insightful)
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.
Re: (Score:3)
Why the hell were you storing / manipulating a 64-bit key in a tree class as floating-point?
Re: (Score:3)
Why the hell were you storing / manipulating a 64-bit key in a tree class as floating-point?
One would guess that maybe just maybe the natural type of the key was floating point? So then what unnatural type would you suggest he should have used in its place?
Yes, comparing floating-point numbers is tricky and you have to aware of the issues. No, it is not always wrong to compare them, nor to use them as keys. Would you really argue that it is inappropriate for a database to provide the ability to index a floating-point column???
Re: (Score:2)
No, it is not always wrong to compare them, nor to use them as keys.
That's like saying that it's not always wrong to kill someone. While it's technically true, it's still probably wrong if you're thinking of doing it.
Re: the 80 bit issue is well known (Score:2)
Re: (Score:1)
perhaps because it's a floating point value?
how else would you compare it?
ie - what the bleep are you on about?
Re:the 80 bit issue is well known (Score:4, Funny)
"I don't mix GCC with msvcrt so I am not sure how old / new this is." Why anybody WOULD mix the two and ever expect anything to work, ever, is kind of beyond me. I guess if you have a week to go through everything line-by-line and your project is manageably small enough to do so.
yeah why would you link a windows application against windows ui dll's? maybe to display something using them..
Re: (Score:2)
People mix msvcrt and GCC all the time if they are working on Windows. The Windows port of GCC (MingW) uses msvcrt.dll for a large chunk of its C Runtime.
Re: (Score:2)
Shorthand for "I'm making stuff up".
The gcc compiler has command line flags to force all floating point expressions to be evaluated strictly using 64bits in register without using the additional 16 bits available. It is that well known.
Re: (Score:2)
That has nothing to do with TFA. In gcc, long double is 80-bit when stored so not only it is computed at full x87 precision, that precision is retained. In VC, long double is effectively an alias for double. Both compilers compute with full precision for intermediate values, but that's not the problem here; the problem is that the type with the same name has different representation between them.
64 bits (Score:3)
Re: (Score:3)
64 bits should be enough for anybody
Yes, and 80bit floating point gives you exactly 64 significant bits ;)
Re: (Score:2)
It's nice to know we can rely on the Anonymous Cow-patty to be wrong and insulting at the same time.
Go kill yourself. You'll feel better.
Useful to know... (Score:5, Insightful)
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?
exactly (Score:5, Informative)
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... [arstechnica.com]
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... [gnome.org]
Something seems to be badly garbled in the story (Score:2)
Gnu C "long double" is 16 bytes long and most decidedly does not fit into 80 bytes.
Re: (Score:2)
That should be "80 bits"...
Re: (Score:3)
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.
Re: (Score:2)
It has to do that because arrays of types are required to not have gaps between elements (so that address arithmetic works), and on the other hand they all have to be properly aligned. For modern Intel CPUs, the proper alignment for an 80-bit float is 8 bytes. Hence the smallest value that is equal to or greater than 10 bytes (80 bits) that is divisible by 8 - 16 bytes.
Re: (Score:2)
I don't know about vanilla Mingw, but tdm is on 4.9.2 - just tested, no bug.