Earlier quoted context omitted.
Probably the author is accidentally getting 80-bit "extended double" arithmetic.
That should be clear from looking at the assembly, shouldn't it? Don't think the floating point environment can change that but I could be wrong. Floating-point rounding modes seem more likely to me. The author should be able to dump the floating point configuration to confirm, I'm sure.
Weird compiler bug – Same code, different results
31–40 of 41 posts
Re: Weird compiler bug – Same code, different results
#32Earlier quoted context omitted.
That should be clear from looking at the assembly, shouldn't it? Don't think the floating point environment can change that but I could be wrong. Floating-point rounding modes seem more likely to me. The author should be able to dump the floating point configuration to confirm, I'm sure.
The same x86 instructions are used for arithmetic on float/double/extended types; the difference is a precision setting in the x87 control word.
Re: Weird compiler bug – Same code, different results
#33Do not use C/C++ for numerical code where accuracy is needed. These languages are not specified to conform to IEEE 754 and you are absolutely asking for trouble.
In practice, all of the C compilers will (or can be made to) conform to IEEE 754, although #pragma STDC FENV_ACCESS ON support is very spotty (and consequently non-default rounding-mode support), although Clang/LLVM has been working on this for the past several months. (That reminds me, I need to harangue the llvm-libc folks to add that pragma to their fpenv code for correctness sake).
Re: Weird compiler bug – Same code, different results
#34Earlier quoted context omitted.
The same x86 instructions are used for arithmetic on float/double/extended types; the difference is a precision setting in the x87 control word.
Well in most cases I've looked at generated assembly (not that often), the xmm registers are used even for scalar operations, which I thought was the default option for gcc on x86-64, but I suppose it might differ on different systems (or perhaps 32-bit mode was used for some reason).
Re: Weird compiler bug – Same code, different results
#35> This means that floating point arithmetic is non-associative. In that A + B != B + A. The equation is the commutative property, not associative. IIRC addition in IEEE-754 is commutative. The property that fails is (A+B)+C = A+(B+C).
Op Here. Yes you are correct. Been very sleep derived when I wrote this (newborns eh). I'll update this. I didn't want to go too far into the background of floating point math in the post as it wasn't ultimately the issue, just something I was mindful of.
> Update: Thanks to gus_massa and wiml @ HackerNews for pointing out I had used associative instead of commutative.... This means that floating point arithmetic is noncommutative [i]n that A + B != B + A.
Floating-point arithmetic is commutative, but not associative. So for floating-point numbers,
A + B = B + A always, but
A + (B + C) != (A + B) + C in many cases.
The problem comes about from significant digits and rounding - A + B might round up to 1, but B + C might round down to zero, etc. The point remains that the order in which you do things actually does matter in floating-point arithmetic, but it's the order you compute the "inner parentheses," not the actual order of numbers in (e.g.) the FPU registers.
Re: Weird compiler bug – Same code, different results
#36Do not use C/C++ for numerical code where accuracy is needed. These languages are not specified to conform to IEEE 754 and you are absolutely asking for trouble.
Keep in mind that C++ doesn't exist. The compilers all have ways of enforcing compliance. Intel C++ seems to be pretty naughty in that it effectively has fast-math on by default.
Why did you post this?
Re: Weird compiler bug – Same code, different results
#37Earlier quoted context omitted.
Op Here. Yes you are correct. Been very sleep derived when I wrote this (newborns eh). I'll update this. I didn't want to go too far into the background of floating point math in the post as it wasn't ultimately the issue, just something I was mindful of.
I think you made the wrong correction in the article: > Update: Thanks to gus_massa and wiml @ HackerNews for pointing out I had used associative instead of commutative.... This means that floating point arithmetic is noncommutative [i]n that A + B != B + A. Floating-point arithmetic is commutative, but not associative. So for floating-point numbers, A + B = B + A always, but A + (B + C) != (A + B) + C in many cases.…
Re: Weird compiler bug – Same code, different results
#38I would have never thought that the output of some floating point operations depend on the „reset of the floating point package“. What gives?
Things like rounding mode and denornal behavior could be controlled by CPU flags. Imy not familiar with x86, but this is defiy the case in PPC.
Re: Weird compiler bug – Same code, different results
#39I would have never thought that the output of some floating point operations depend on the „reset of the floating point package“. What gives?
The processor itself supports configuring some aspects of floating point behavior; on x86 this is the MXCSR register. The most important one is rounding mode: you can choose round-to-nearest, round-down, round-up, or round-towards-zero. Less common options include whether to raise an exception on various out-of-range conditions, and whether to treat denormal numbers as zero (faster but less accurate and not IEEE 754…
Re: Weird compiler bug – Same code, different results
#40Earlier quoted context omitted.
So, what should be used?
The correct - but useless - answer is: any language that's IEC 60559:xxxx conformant. Examples are: Fortran, R, C#, Java, D and many others. You'd need to refer to a language's specification to find out, though some aren't very well defined. zig comes to mind; it supports the data types and offers strict mode, but doesn't explicitly state its IEE 754:2008 compliance.