On Tue, 18 Jan 2005, James E Wilson wrote:
On Tue, 2005-01-18 at 14:31, Chris Lattner wrote:Aren't F1, F2, and F3 identical?
Yes.
The problem case would be something like float Y, Z; float X = (float)Y + (float)Z; and float X = (float)((double)Y + (double)Z) giving different results, because the second one is liable to double rounding error.
Ah, interesting, I did not know that. I guess if you wanted REALLY inefficient code, the way to do this would be to play with the X86 precision register.
Double rounding error can occur when the result of the add is almost exactly half way between two representable float values. Using decimal for convenience, suppose the unrounded result of the add is something like 00...005,4999999999,999 where the first comma represents the rounding point for float, and the second comma represents the rounding point for double. If we round this directly to float, we get 00...005. If we round this to double, we get 00...005,500..00. If we then round this to float, we get 00...006. Thus double rounding can introduce a single bit error in the least significant bit of the result.
I see.
If you are using x87 long double arithmetic, and converting the result to float/double, then you will get double rounding errors. Double rounding errors will be rare, and probably will affect few programs, but it does mean that the results are still not exactly the same as the results you will get on sparc/mips/power/x86_64/etc. If the only problem you have is double rounding, then you are certainly much better off than the current x87 FP gcc support though.
Okay, thanks for the clarification. You're absolutely right, we are susceptible to double rounding errors.
The only way to avoid double rounding is to have separate float, double, and long double arithmetic instructions, which unfortunately the x87 FP unit doesn't have.
I believe changing the precision fields would work, but at some point you're better off using soft-float...
-Chris
-- http://nondot.org/sabre/ http://llvm.cs.uiuc.edu/