Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-11

fpc 32 / 64 bit / c++/ floating point question

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Helmut Hartl

While stabilizing my bullet physics port i saw some differences in floating point behaviour between c++ and fpc32 and fpc 64 bit.

In question is a simple dot product.

The function :
result := a*d+b*e+c*f;

Gives "different" results( 6.3846106530 vs 6.3846111610 ) depending on the usage of intermediate variables for the final result and the fpc version
32 bit / 64 bit, while the C++ version does not show this behaviour and always
gives the same result. (XCode 3.2.1/ GCC on OSX)

I only show the (extracted) compilable fpc exampe:

program fpc_floatmul;
var a,b,c,d,e,f      : single;
     i,j,k                   : single;
     result_same_as_c : single;
begin
   a:= 1;
   b:= -5.65984446;
   c:= -3.4953573;
   d:= 8.48976051;
   e:= 1.5;
   f:= -1.82659933;
   i := a * d;
   j := b * e;
   k := c * f;
   result_same_as_c := i + j + k;
   writeln(result_same_as_c:10:10);
   writeln(a*d+b*e+c*f:10:10); // different result
end.

Running the above program gives
1) C++ / FPC 64 Bit
6.3846106530
6.3846106530
2) FPC32 Bit
6.3846106530
6.3846111610

Is this explainable or wrong behaviour ?

thanks,
helmut

Reply by email

Vinzent Höfler
Helmut Hartl wrote 9 lines
Running the above program gives 1) C++ / FPC 64 Bit 6.3846106530 6.3846106530 2) FPC32 Bit 6.3846106530 6.3846111610 Is this explainable or wrong behaviour ?

First suspect candidate: the intermediate results are calculated with the 80-bit "temporary" float of the FPU on x86-32, while this is not the case on the 64 bit target.

Vinzent.

Reply by email

Michael Müller
to Helmut Hartl: While stabilizing my bullet physics port i saw some differences in floating point…
Helmut Hartl wrote 43 lines
While stabilizing my bullet physics port i saw some differences in floating point behaviour between c++ and fpc32 and fpc 64 bit. In question is a simple dot product. The function : result := a*d+b*e+c*f; Gives "different" results( 6.3846106530 vs 6.3846111610 ) depending on the usage of intermediate variables for the final result and the fpc version 32 bit / 64 bit, while the C++ version does not show this behaviour and always gives the same result. (XCode 3.2.1/ GCC on OSX) I only show the (extracted) compilable fpc exampe: program fpc_floatmul; var a,b,c,d,e,f : single; i,j,k : single; result_same_as_c : single; begin a:= 1; b:= -5.65984446; c:= -3.4953573; d:= 8.48976051; e:= 1.5; f:= -1.82659933; i := a * d; j := b * e; k := c * f; result_same_as_c := i + j + k; writeln(result_same_as_c:10:10); writeln(a*d+b*e+c*f:10:10); // different result end. Running the above program gives 1) C++ / FPC 64 Bit 6.3846106530 6.3846106530 2) FPC32 Bit 6.3846106530 6.3846111610 Is this explainable or wrong behaviour ?

Single has 7 significant digits. So it makes no sense to write more since you can't trust them. If you use in your case 10:6 instead of 10:10 in writeln() you'll get in all cases '6.384611'. And it makes no sense to store a value with more than these number of digits into a Single type. So perhaps the equation in the last writeln() is done internally in a higher precision than Single. When I use a calculator that can handle all you specified digits than I get 6,384611122290609 which is closer to the last result. What do you get when you replace Single and float by Double?

Michael

Reply by email

Vinzent Höfler
Michael Müller wrote
Single has 7 significant digits.

<mode style="nitpicking">
Six significant digits. The seventh already is unreliable. </mode>

Vinzent.

Reply by email

Marco van de Voort
to Vinzent Höfler

In our previous episode, Vinzent H?fler said:

Show quoted text 7 lines
wrote: > Single has 7 significant digits. <mode style="nitpicking"> Six significant digits. The seventh already is unreliable. </mode>

A mistake in the nth digit can show up much higher than the nth or n-1th digit, depending on the magnitude of the condition number.

A commonly known case of an error in inputs propagating to large errors in output is catastrophic cancellation, which can cause a condition number >>1. And the example _does_ add negative values to positive ones, which is equal to the subtraction in catastrophic canellation.

Reply by email

Helmut Hartl
to Vinzent Höfler: On Sun, 21 Nov 2010 18:54:13 +0100, Helmut Hartl First suspect candidate: the…
Vinzent Höfler wrote 14 lines
On Sun, 21 Nov 2010 18:54:13 +0100, Helmut Hartl wrote: > Running the above program gives > 1) C++ / FPC 64 Bit > 6.3846106530 > 6.3846106530 > 2) FPC32 Bit > 6.3846106530 > 6.3846111610 > > Is this explainable or wrong behaviour ? First suspect candidate: the intermediate results are calculated with the 80-bit "temporary" float of the FPU on x86-32, while this is not the case on the 64 bit target.

Thanks for the idea - Looking a bit (one eyed) at the generated code this seems to be the most likely reason.
I just gave up on the idea of comparing c++ / and fpc's calculations directly.

helmut

Reply by email