Code: Select all
PROCEDURE PiA () : REAL;
BEGIN RETURN Math.Pi() END PiA;
PROCEDURE PiB () : REAL;
VAR
x : REAL;
BEGIN x := Math.Pi(); RETURN x END PiB;
PROCEDURE Pi*;
BEGIN
ASSERT (PiA() = PiB(), 40);
ASSERT (PiB() = PiA(), 45)
END Pi;
(Ok, the answer would have to be TRAP 45, or it would not be an interesting question.)
I agree with Louwy that this behaviour is confusing, but I do not agree that this is a reason to choose 64-bit accuracy, or that choosing 64-bit accuracy is the solution to this issue.Louwy wrote:...make some simple expression like Math.Pi() == Math.Pi() get a FALSE result(like BB),
will confuse normal users. so most compiler select float64 as default(internal) precision.
One solution is to choose 64-bit accuracy consistently, another is to choose 80-bit accuracy consistently.
I propose that we alter the compiler so that when it spills the FPU registers to RAM it copies all 80 bits, not just 64 bits as now.
The advantages:
1 - Marginal extra accuracy in a few calculations.
2 - It avoids confusing results like the examples above
3 - It makes the floating point behaviour much easier to predict, and so greatly aids the analysis required to write correct algorithms by design.
To me point 3 is the important one.
Currently it is virtually impossible to even check if two different implementations of a function return the same results.
This proposal does not require any changes to the Language Report.
The disadvantages:
1 - A very small stack memory overhead - trivial!
2 - A small speed overhead - probably, pending measurements, too small to see.
3 - It will break existing code that relies on "Math.Pi() = Math.Pi()" returning FALSE.
I regard such code as pretty undesirable, but we would need to put a warning in the release notes.
Before taking this discussion much further does someone with compiler expertise have an opinion on the difficulty of implementing this proposal?
-- Edited to correct two spelling mistakes