Some corrections, see below ...

Am 03.10.2018 um 11:54 schrieb Bernd Oppolzer:
The explanation for the results is as follows:

the first three codings do the multiplication first, then the division.
the last two first division, then multiplication. That makes the difference.

When division is done first, you get an intermediate result of 1.0 exactly.

This is correct, because the same two input values go into the division.
1.0 can be represented correctly as FP value.

The subsequent multiplication yields 51009.9 exactly, so the difference is zero.

Wording needs improvement; the value is not 51009.9 exactly, but it is the
nearest machine number, which is the same as the other operand (the same
number multiplied by 1.0) of the subtraction, so the result will be zero.

No risk for rounding errors.

When the multiplication is done first, you get a very large result which cannot
be stored exactly in the machine representation. When divided by 51009.9,
the result differs by a little epsilon from 1.0, so the difference is shown

Should be:
the result may differ by a little epsilon from the original machine representation
of 51009.9; this epsilon may be shown instead of zero.

as the final result.

Depending on the FP representation chosen, you will see the difference or not.
When I tested the program with my New Stanford Pascal compiler, I saw the
different computation sequence in the generated code, but I didn't get a
difference. But that's pure luck.

Example:

this is in fact the real P-Code produced by the New Stanford compiler
for the hypothetical stack machine; different for the two cases.


Multiplication first:

 LOC 21
 LOD R,1,416
 LOD R,1,408
 LOD R,1,416
 MPR
 LOD R,1,424
 DVR
 SBR
 STR R,1,432

Division first:

 LOC 23
 LOD R,1,416
 LOD R,1,408
 LOD R,1,416
 LOD R,1,424
 DVR
 MPR
 SBR
 STR R,1,432

The result was zero in both cases.

Kind regards

Bernd



Am 03.10.2018 um 10:40 schrieb mailingli...@geldenhuys.co.uk:
I have this simple little test. My expected answer for all the calculations are 0 (zero), but both FPC and Delphi give different results. Java is the only one that seems consistent regarding the results.

Can anybody explain this, especially the first 3 very small negative numbers that Delphi and FPC produces? I know  not all floating point values can be stored exactly (or something like that), and when doing calculations, it might do a auto data type conversion. But is any of that taking place here?

The only positive I can see, is that FPC and Delphi are consistent. :-)

Here is the Object Pascal test:

===============[ TestOperatorPrecedence.pas ]=================
program TestOperatorPrecedence;

{$IFDEF FPC}
  {$mode objfpc}{$H+}
{$ELSE}
  {$apptype console}
{$ENDIF}

var
  a,b,c,d: double;
  ans: extended;
begin
  a := 1.0;
  b := 51009.9;
  c := 51009.9;
  d := 51009.9;
  writeln(b);
  writeln(c);
  writeln(d);
  writeln('---');

  ans := c - b * c / d;
  writeln(ans);

  ans := c - (b * c) / d;
  writeln(ans);

  ans := c - (b * c / d);
  writeln(ans);

  ans := c - b * (c / d);
  writeln(ans);


  ans := c - (b * (c / d));
  writeln(ans);
end.
==============================================================

And the results are:
graeme.geldenhuys@UKCM-L500737 C:\devel\tests\OperatorPrecedence
TestOperatorPrecedence.exe
 5.10099000000000E+0004
 5.10099000000000E+0004
 5.10099000000000E+0004
---
-3.55271367880050E-0015
-3.55271367880050E-0015
-3.55271367880050E-0015
 0.00000000000000E+0000
 0.00000000000000E+0000


And here is the Java equivalent...


===============[ TestOperatorPrecedence.java ]================
public class TestOperatorPrecedence {

    public static void main(String[] args) {
        double b = 51009.9;
        double c = 51009.9;
        double d = 51009.9;
        double ans;

        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
        System.out.println("-----");

        ans = c - b * c / d;
        System.out.println(ans);

        ans = c - (b * c) / d;
        System.out.println(ans);

        ans = c - (b * c / d);
        System.out.println(ans);

        ans = c - b * (c / d);
        System.out.println(ans);


        ans = c - (b * (c / d));
        System.out.println(ans);
    }
}

==============================================================

And the results are:
graeme.geldenhuys@UKCM-L500737 C:\devel\tests\OperatorPrecedence
java TestOperatorPrecedence
51009.9
51009.9
51009.9
-----
0.0
0.0
0.0
0.0
0.0



Regards,
  Graeme



_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to