[fpc-pascal] Loss of precision when using math.Max()

Martok listbox at martoks-place.de
Mon Jul 9 16:32:59 CEST 2018


Am 03.07.2018 um 23:10 schrieb Florian Klämpfl:
>> OK, then two questions remain: Why does is occur/apply only for (newer?) 3.1.1 versions?
> I dug a little bit deeper, the reason is:
> https://bugs.freepascal.org/view.php?id=25121I tried figuring this out, sharing what I found here for reference and a workaround.

In the example of 1.0 / 3.0, both numbers are represented exactly in IEEE-754,
so there is no difference caused by this "range-rounding". Typedef passing has
not changed, and the "minimal" types found in the parser at
compiler/pexpr.pas:1711 have not changed for years either.

So the expression is s32real(1.0) / s32real(3.0) {as before}, which then gets
evaluated by taddnode(typ=slashn) at bestreal precision {as before}, and
returned at s32real precision {as before} and "range rounded" to single {this is
new}. It is then stored in a typed const of whatever type was specified {as before}.

To make sure this works, one has to manually make the const expression be of the
type required:
const
  e: Extended = Extended(1.0) / 3.0;

I seem to remember that this was once documented somewhere for Delphi. Can't
seem to find it though, so maybe it was a 3rd-party book? There is no hint of it
in the FPC documentation, anyway.


Regards,
Martok






More information about the fpc-pascal mailing list