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

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

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

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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Vinzent Höfler
On Sun, 21 Nov 2010 18:54:13 +0100, Helmut Hartl <[hidden email]>  
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.


Vinzent.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Michael Müller-10
In reply to this post by Helmut Hartl

Am 21.11.2010 um 18:54 schrieb 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 ?

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_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Vinzent Höfler
In reply to this post by Helmut Hartl
On Sun, 21 Nov 2010 20:35:42 +0100, Michael Müller
<[hidden email]> wrote:

> Single has 7 significant digits.

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


Vinzent.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Marco van de Voort
In our previous episode, Vinzent H?fler said:
> <[hidden email]> 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.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Helmut Hartl
In reply to this post by Vinzent Höfler
Am 21.11.10 19:02, schrieb Vinzent Höfler:

> On Sun, 21 Nov 2010 18:54:13 +0100, Helmut Hartl<[hidden email]>
> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal