View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0037087 | FPC | RTL | public | 2020-05-16 19:22 | 2020-10-25 18:24 |
Reporter | Zoran Vučenović | Assigned To | Florian | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | no change required | ||
Product Version | 3.2.0 | ||||
Fixed in Version | 3.3.1 | ||||
Summary | 0037087: SIGFPE with Val(FloatToStr(MaxDouble)) | ||||
Description | Standard 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. | ||||
Tags | No tags attached. | ||||
Fixed in Revision | |||||
FPCOldBugId | |||||
FPCTarget | - | ||||
Attached Files |
|
|
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. |
|
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) |
|
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. |
|
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) |
|
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. |
|
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 |
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 |