The Extended Pascal real constants have strange values, namely MaxReal=MinReal=EpsReal=NaN.
[pas]% cat const.pas program EPRealConstants (Output);
uses GPC;
var R : Real; OK: Boolean value True;
procedure Bomb (I: Integer); begin WriteLn ('Failed ', I : 2, ': ', R); OK := False end;
begin R := MinReal; if IsNotANumber (R) then Bomb (1); if IsInfinity (R) then Bomb (2); if R <= 0 then Bomb (3); { Simple `if R / 2 <> 0' doesn't work (at least on IA32), since it is internally computed with bigger precision. The same holds for tests # 8 and 13. } R := R / 2; if R <> 0 then Bomb (4);
R := MaxReal; if IsNotANumber (R) then Bomb (5); if IsInfinity (R) then Bomb (6); if R <= 0 then Bomb (7); R := R + R; if not (IsInfinity (R) or (R <= MaxReal)) { `not IsInfinity (R)' alone probably can't work on non-IEEE hardware } then Bomb (8);
R := EpsReal; if IsNotANumber (R) then Bomb (9); if IsInfinity (R) then Bomb (10); if R <= 0 then Bomb (11); R := R + 1; if R <= 1 then Bomb (12); R := EpsReal / 2 + 1; if R <> 1 then Bomb (13);
if OK then WriteLn ('OK') end. [pas]% uname -a ; gpc -v Linux localhost.localdomain 2.4.2-2 #1 Sun Apr 8 19:37:14 EDT 2001 i586 unknown Reading specs from /usr/local/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/specs gpc version 20011222, based on 2.95.2 19991024 (release) [pas]% gpc const.pas [pas]% ./a.out Failed 1: NaN Failed 4: NaN Failed 5: NaN Failed 8: NaN Failed 9: NaN Failed 13: NaN [pas]%
I'm not quite sure if the testing program above is robust enough, but it passed on my machine when I replaced manually the constants with their correct (IMHO) values (1.7976931348623157e+308, 4.9406564584124654e-324, 2.2204460492503131e-16).
Emil Jerabek
Emil Jerabek wrote:
The Extended Pascal real constants have strange values, namely MaxReal=MinReal=EpsReal=NaN.
[pas]% cat const.pas program EPRealConstants (Output);
uses GPC;
var R : Real; OK: Boolean value True;
procedure Bomb (I: Integer); begin WriteLn ('Failed ', I : 2, ': ', R); OK := False end;
begin R := MinReal; if IsNotANumber (R) then Bomb (1); if IsInfinity (R) then Bomb (2); if R <= 0 then Bomb (3); { Simple `if R / 2 <> 0' doesn't work (at least on IA32), since it is internally computed with bigger precision. The same holds for tests # 8 and 13. } R := R / 2; if R <> 0 then Bomb (4);
R := MaxReal; if IsNotANumber (R) then Bomb (5); if IsInfinity (R) then Bomb (6); if R <= 0 then Bomb (7); R := R + R; if not (IsInfinity (R) or (R <= MaxReal)) { `not IsInfinity (R)' alone probably can't work on non-IEEE hardware } then Bomb (8);
R := EpsReal; if IsNotANumber (R) then Bomb (9); if IsInfinity (R) then Bomb (10); if R <= 0 then Bomb (11); R := R + 1; if R <= 1 then Bomb (12); R := EpsReal / 2 + 1; if R <> 1 then Bomb (13);
if OK then WriteLn ('OK') end. [pas]% uname -a ; gpc -v Linux localhost.localdomain 2.4.2-2 #1 Sun Apr 8 19:37:14 EDT 2001 i586 unknown Reading specs from /usr/local/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/specs gpc version 20011222, based on 2.95.2 19991024 (release) [pas]% gpc const.pas [pas]% ./a.out Failed 1: NaN Failed 4: NaN Failed 5: NaN Failed 8: NaN Failed 9: NaN Failed 13: NaN [pas]%
Please try adding `#include <float.h>' to p/gpc-dec.c.
: { Simple `if R / 2 <> 0' doesn't work (at least on IA32), : since it is internally computed with bigger precision. : The same holds for tests # 8 and 13. }
When compiling with optimization, you'll also have to declare `R : volatile Real;' or use other means to prevent the optimizer from keeping the result in registers, computed with higher precision.
Then still test #4 fails on my system, and I think it is allowed to fail. The requirement on MinReal and MaxReal is not (as one might expect) that they are the smallest and largest real values
0, but: "The values of minreal and maxreal shall be such that
arithmetic in the set including the closed interval - maxreal to maxreal, but excluding the two open intervals - minreal to zero and zero to minreal can be expected to work with reasonable approximations, but arithmetic outside this set cannot be expected to work with reasonable approximations." (ISO 10206, 6.4.2.2 b).
Therefore, on a system that supports denormalized floating point numbers (such as IA32), I gather the MinReal should contain the smallest normalized number which it seems to do.
Frank
Frank wrote:
Please try adding `#include <float.h>' to p/gpc-dec.c.
thanks, I'll try that.
When compiling with optimization, you'll also have to declare `R : volatile Real;' or use other means to prevent the optimizer from keeping the result in registers, computed with higher precision.
Then still test #4 fails on my system, and I think it is allowed to fail. The requirement on MinReal and MaxReal is not (as one might expect) that they are the smallest and largest real values
0, but: "The values of minreal and maxreal shall be such that
arithmetic in the set including the closed interval - maxreal to maxreal, but excluding the two open intervals - minreal to zero and zero to minreal can be expected to work with reasonable approximations, but arithmetic outside this set cannot be expected to work with reasonable approximations." (ISO 10206, 6.4.2.2 b).
Therefore, on a system that supports denormalized floating point numbers (such as IA32), I gather the MinReal should contain the smallest normalized number which it seems to do.
That's true, I didn't realize this problem. I think a modified version of the test could pass:
--------------------------------------------------- program EPRealConstants (Output);
uses GPC;
var R, S: volatile Real; OK: Boolean value True;
procedure Bomb (I: Integer); begin WriteLn ('Failed ', I : 2, ': ', R); OK := False end;
begin R := MinReal; if IsNotANumber (R) then Bomb (1); if IsInfinity (R) then Bomb (2); if R <= 0 then Bomb (3); S := R * (1 + EpsReal); if S <= R then Bomb (41); R := R / 2; S := R * (1 + EpsReal); if S > R then Bomb (42);
R := MaxReal; if IsNotANumber (R) then Bomb (5); if IsInfinity (R) then Bomb (6); if R <= 0 then Bomb (7); R := R + R; if not (IsInfinity (R) or (R <= MaxReal)) { `not IsInfinity (R)' alone probably can't work on non-IEEE hardware } then Bomb (8);
R := EpsReal; if IsNotANumber (R) then Bomb (9); if IsInfinity (R) then Bomb (10); if R <= 0 then Bomb (11); R := R + 1; if R <= 1 then Bomb (12); R := EpsReal / 2 + 1; if R <> 1 then Bomb (13);
if OK then WriteLn ('OK') end. ----------------------------------------------
Emil Jerabek
Emil Jerabek wrote:
Then still test #4 fails on my system, and I think it is allowed to fail. The requirement on MinReal and MaxReal is not (as one might expect) that they are the smallest and largest real values
0, but: "The values of minreal and maxreal shall be such that
arithmetic in the set including the closed interval - maxreal to maxreal, but excluding the two open intervals - minreal to zero and zero to minreal can be expected to work with reasonable approximations, but arithmetic outside this set cannot be expected to work with reasonable approximations." (ISO 10206, 6.4.2.2 b).
Therefore, on a system that supports denormalized floating point numbers (such as IA32), I gather the MinReal should contain the smallest normalized number which it seems to do.
That's true, I didn't realize this problem. I think a modified version of the test could pass:
Clever trick! ;-) Works on my system (IA32, Linux and DJGPP). Will check on other machines later.
Frank
I wrote:
Emil Jerabek wrote:
Then still test #4 fails on my system, and I think it is allowed to fail. The requirement on MinReal and MaxReal is not (as one might expect) that they are the smallest and largest real values
0, but: "The values of minreal and maxreal shall be such that
arithmetic in the set including the closed interval - maxreal to maxreal, but excluding the two open intervals - minreal to zero and zero to minreal can be expected to work with reasonable approximations, but arithmetic outside this set cannot be expected to work with reasonable approximations." (ISO 10206, 6.4.2.2 b).
Therefore, on a system that supports denormalized floating point numbers (such as IA32), I gather the MinReal should contain the smallest normalized number which it seems to do.
That's true, I didn't realize this problem. I think a modified version of the test could pass:
Clever trick! ;-) Works on my system (IA32, Linux and DJGPP). Will check on other machines later.
I tested it on Sparc (Solaris) now, and 42 failed. I'm not convinced that it should succeed everywhere (what exactly is "reasonable approximation"?), so I'm commenting it out. Perhaps you have another idea how we can check it ...
Frank