1
votes

Something has changed with System.Str in Delphi XE2. The following procedure :

procedure someProcedure;
var 
  E:double;
  outString:string;
begin
  E:=-1.7E+308;
  Str(E:i:j, outString);
end;

Raises an access violation

(exception class $C0000005, access violation at 0x00407318: read of address 0x30303028)

in Delphi XE2 where 'i' and 'j' are whatever integers. This same code works fine in Delphi 2010 and returns outString = '-1.7E+0308'. Similar code is used in a few of the TurboPower Orpheus components and it causes the entire IDE to crash on a BEX error.

This is in Win7 64-bit. Any ideas?

Edit : extra info

This seems to happen only with large negative numbers. Str seems to generate long strings which break when they exceed ~130 characters.

Note : this does not break when using only width (where i = some width)

procedure someProcedure;
var 
  E:double;
  outString:string;
begin
  E:=-1.7E+308;
  Str(E:i, outString);
end;
1
That's not a precision error. That's just the fact that -1.6E117 is not exactly representable in binary floating point format. - David Heffernan
As a workaround you probably can just test if it's smaller than 0, negate the sign and then prefix '-' to the string. - CodesInChaos
Actually XE2 is getting it right. 1.60000000000000002E+0117 is correct. See Rob Kennedy's most useful page: pages.cs.wisc.edu/~rkennedy/exact-float?number=-1.6e117 - David Heffernan
@J... No, 32 bit Delphi D2010, XE2 etc. will not retain -1.6e+117 as an Extended value once you push it into a variable. The Delphi compiler does not perform floating point optimisations which would be needed for that to happen. Essentially the compiler would need to optimise the variable into a floating point register. It does not do that. The difference must be solely in Str. The basic handling of floating point arithmetic, for the 32 bit compiler, is unchanged between D2010 and XE2. - David Heffernan
No worries. It's a tricky subject. It just happens to be a point of special interest to me because my day job involves numerical computation. And regressions and changes in the way the compiler behave are very important to me. I don't think the 32 bit compiler has changed much for years and years. - David Heffernan

1 Answers

7
votes

It's clearly a bug with the handling of large magnitude negative numbers. Positive numbers are handled fine. If you can intercept the calls to Str then you could make sure that you only ever call Str passing positive numbers and then prefix the - yourself.

I have submitted the bug to Quality Central: QC#103436.