View Issue Details

IDProjectCategoryView StatusLast Update
0037087FPCRTLpublic2020-10-25 18:24
ReporterZoran Vučenović Assigned ToFlorian  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionno change required 
Product Version3.2.0 
Fixed in Version3.3.1 
Summary0037087: SIGFPE with Val(FloatToStr(MaxDouble))
DescriptionStandard Pascal Val procedure raises SIGFPE.
As Val should never raise exception, but only return non-zero value in third parameter, this is even more annoying bug.

Steps To Reproduce(tested on Windows 7, 32-bit):

program TestVal;

uses SysUtils, Math;

var
  D: Double;
  S: AnsiString;
  E: Word;
begin
  D := Math.MaxDouble;
  WriteLn(D);
  S := FloatToStr(D);
  Writeln(S);
  Val(S, D, E); // SIGFPE here!
  WriteLn(D);
  ReadLn;
end.

Additional Information- the declaration of Math.MaxDouble is changed in FPC 3.2
in 3.0.4 it was:
MaxDouble = 1.7e+308;
And in 3.2 it is:
MaxDouble = 1.7976931348623157e+308;
Therefore the example I gave needs 3.2 to reproduce the bug.

- If you replace the line "S := FloatToStr(D);" with "Str(D, S);" or "WriteStr(S, D);", the bug dissapears!
The difference is only in + sign in front of the exponent:
FloatToStr returns "1.7976931348623157e308" (no + in front of the exponent)
Str(D, S) returns "1.7976931348623157e+308" (notice + in front of the exponent - e+308)

Then, Val gives SIGSEGV only when this "+" sign is not present in front of the exponent.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget-
Attached Files

Activities

Zoran Vučenović

2020-05-16 19:28

reporter   ~0122860

Version 3.2 is not listed in combo box, so I chose 3.3.1, but I actually tested in 3.2.
I want to report this bug in 3.2, which is about to be released. I hope this can be fixed there.

nanobit

2020-05-16 22:02

reporter   ~0122863

1.7976931348623157e+308 has 17 significant digits.
FloatToStr() uses only 15, thus rounds up and returns larger value
which leads either to EOverflow in val() or to +inf (if EOverflow is masked)

Zoran Vučenović

2020-05-16 22:18

reporter   ~0122864

Thanks, Nanobit, but, as I said already (in "Additional information"), FloatToStr returns '1.7976931348623157e308', so all 17 significant digits are used.
As I also pointed there, the difference with Str(D, S) is only in that FloatToStr doesn't put '+' sign in front of the exponent part.

And, when the exponent does not have this '+' sign, Val fails with SIGFPE.
Hm... The failure receipt seems to be - 17 significant digits and exponent without sign.

nanobit

2020-05-16 22:47

reporter   ~0122866

This works for me without exception:
S := '1.7976931348623157e308';
Val(S, D, E); // D obtains the same value
(but I have some fpc3.2 beta)

NoName

2020-05-17 01:09

reporter   ~0122869

Last edited: 2020-05-17 01:09

View 2 revisions

Problem is maybe the x87 fpu which is used on 32bit?
Maybe the new precision of the value should be documented as it could break code.

Florian

2020-10-25 18:24

administrator   ~0126548

Converting float numbers back and forth to strings might result indeed in unprecise results.

The change is documented: https://wiki.freepascal.org/User_Changes_Trunk#Math_Min.2FMaxSingle.2FDouble

Issue History

Date Modified Username Field Change
2020-05-16 19:22 Zoran Vučenović New Issue
2020-05-16 19:28 Zoran Vučenović Note Added: 0122860
2020-05-16 20:21 Jonas Maebe Product Version 3.3.1 => 3.2.0
2020-05-16 20:21 Jonas Maebe FPCTarget => -
2020-05-16 22:02 nanobit Note Added: 0122863
2020-05-16 22:18 Zoran Vučenović Note Added: 0122864
2020-05-16 22:47 nanobit Note Added: 0122866
2020-05-17 01:09 NoName Note Added: 0122869
2020-05-17 01:09 NoName Note Edited: 0122869 View Revisions
2020-10-25 18:24 Florian Assigned To => Florian
2020-10-25 18:24 Florian Status new => resolved
2020-10-25 18:24 Florian Resolution open => no change required
2020-10-25 18:24 Florian Fixed in Version => 3.3.1
2020-10-25 18:24 Florian Note Added: 0126548