Answer 1. You have an old Linux system which behaves sensibly. More recent versions of libc will give you the less desirable IEEE-recommended default behaviour which you have observed on the proprietary system. If you really want the IEEE-recommended behaviour, you should upgrade your libc. A better move would be to fix the bug in your program.
If you want more sophisticated behaviour, you might like to try the wmexcep package.
Answer 2. You have a recent Linux system which has a version of libc which gives you the less desirable (my opinion) IEEE-recommended default behaviour.
If you want to get sigfpe's, or more sophisticated behaviour, you might like to try the wmexcep package.
Answer 3. There are a few forms of this, one example is:
double a, b, c; [code which assigns b and c here] a = b * c; if ( a != b * c ) printf("gcc is bugged!\n");This may print the error message because the assignment to "a" causes the result of "b * c" to be converted to a 'double' (which is 53 bit precision on (Intel) Linux). However, the result of "b * c" has 64 bits of precision on the same machine. The comparison is comparing a 53 bit precision quantity with one which has 64 bit precision. The result of the comparison will often (but not always) be true (unequal).
Another example is:
double a, b; [code which assigns b here] a = sin(b); if ( a != sin(b) ) printf("gcc is bugged!\n");Similar to the first case, the result of the comparison will often (but not always) be true (unequal). The reason in this case lies in the fact that gcc uses floating point registers for function returns. A register holds a 64 bit precision quantity. Once again, the comparison is comparing a 53 bit precision quantity with one which has 64 bit precision. (note that the FPU "transcendental" functions always return a 64 bit precision result)
Note that if optimization is used, gcc may attempt to keep variables in registers. In this case it is possible that "a" will actually have 64 bit precision and the result of the comparisons in the above examples will be false (equal).
Yet another example, from a posting to the net, can be found here. Discussion of other effects of rounding precision can be found in the answers to the next two questions.
Answer 4. Under Intel Linux, the FPU is usually run in 64 bit precision (i.e. the precision of a long double) mode all of the time. For example multiplying two 53 bit precision (the precision of a C double) numbers produces a 64 bit precision result which is only converted to 53 bit precision when the result is written to memory from the FPU.
The higher precision leads to results which can differ from those obtained on a machine which always produces 53 bit precision results.
Intel machines can be made to run in 53 bit precision mode. See my notes on IEEE-style rounding for more discussion. Questions 3 and 5 also deal with this topic.
People will complain to Linux groups if a program will run on another machine but not on a Linux machine. One might expect that it should be possible to have programs which produces better results in a 64 bit precision mode than when in a 53 bit precision mode; after all, it is greater precision. This is of course true.
Answer 5. Without optimisation, gcc is less likely to keep floating point variables and intermediate results in the registers of the FPU. As a consequence, the results produce by a program which is compiled without optimisation are more likely to be the same as those obtained on other machines. See the answers to questions 3 and 4 (above) for more discussion.