Re: [go-nuts] Possible float64 precision problem

2022-03-10 Thread christoph...@gmail.com
Thank you for offering your help. 

I can now definitely confirm that there is no computation difference 
between Go and C in my program. There is thus no red flag to use Go in our 
scientific application. What a relief. 

The problem is that our C and Go programs don't store the values in the 
same location. I thus compared different values, but they were close enough 
to be confusing. 

It is impressive that the C and Go computation yields the exact same values 
and output when using %g. I could locate my values with a simple text 
search and diagnose their misplacement. I still need to determine which of 
the C or Go program is doing it wrong. This code translation process may 
have uncover a bug in the C program. 
Le jeudi 10 mars 2022 à 00:31:25 UTC+1, pdc...@gmail.com a écrit :

> Hi Christopher, what input int64 is leading to this result (difference in 
> behavior between Go & C). Does it happen with any input?
> I'm asking because I'm interested in playing around with this a bit, maybe 
> writing two trivial programs (one on each language) and comparing the 
> machine code generated from each one. I'm trying to venture into low level 
> debugging/reverse engineering and I think it will be a good exercise.
>
> Thank you!
>
> Best
>
> Pablo
>
> On Wed, Mar 9, 2022, 4:39 PM 'Dan Kortschak' via golang-nuts <
> golan...@googlegroups.com> wrote:
>
>> On Wed, 2022-03-09 at 03:37 -0800, christoph...@gmail.com wrote:
>> > I'm translating a scientific C program into Go that is doing some
>> > 64bit floating point operations.
>> >
>> > In this process I check that the same input yields the same output.
>> > Unfortunately they don't yield the same result, though the
>> > computation is simple. It is as follow. I receive a 64bit integer
>> > value.
>> >
>> > This value is converted to float64/double, and divided by 2^64.
>> > The resulting number is multiplied by 1e8.
>> >
>> > With C I get 41 6E 84 FD 00 09 90 D7, with Go I get 41 6E 84 FD 00 09
>> > E6 8E. The last 15bits are different. The computation is performed
>> > with the same computer.
>> >
>> > Could it be that the C program is performing the computation with
>> > long double (80 bit) precision and that Go is doing it with 64bit
>> > precision ?
>> >
>> > Is there something I could do about it because that might be a red
>> > flag for replacing the C program with a Go program.
>>
>> This is not very surprising depending on the algorithms that are being
>> used/the problem that is being solved. Some problems are fundamentally
>> difficult to solve exactly and the nature of floating point makes them
>> sensitive to the precise set of operations used, intermediate rounding
>> and the order of operations (even for operations that are commutative
>> in theory). As Robert said, knowing the C compiler will be important,
>> and I'd go further, knowing which platform you are building the Go
>> program on can be important due to differences in how floating point
>> operations are rendered into machine code by the compiler, or even how
>> the processor orders apparently commutative operations.
>>
>> Assuming the values that you've pasted above are big endian, then the
>> Go value is within a 1e12th of the value calculate by C (
>> https://go.dev/play/p/dn7G2LI75RC). This is not terrible, and maybe
>> that level of precision is all that can be promised by the algorithm
>> (and believing digits smaller that 1e-12 is dangerous). Alternatively
>> there is no fundamental limit at this point and there is a better more
>> stable algorithm that you can use (though you are only four orders of
>> magnitude from the machine epsilon
>> https://en.wikipedia.org/wiki/Machine_epsilon, so be aware).
>>
>> Floats are tricky beasts and can easily trip people up. I would suggest
>> that you read
>> https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html (and
>> the more friendly https://floating-point-gui.de/).
>>
>>
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>>
> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/ee58b6e5ad163014b256d249e21c875307fecddb.camel%40kortschak.io
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/027222f6-8f42-4db8-ab5c-b34020cd42a6n%40googlegroups.com.


Re: [go-nuts] Possible float64 precision problem

2022-03-09 Thread Pablo Caballero
Hi Christopher, what input int64 is leading to this result (difference in
behavior between Go & C). Does it happen with any input?
I'm asking because I'm interested in playing around with this a bit, maybe
writing two trivial programs (one on each language) and comparing the
machine code generated from each one. I'm trying to venture into low level
debugging/reverse engineering and I think it will be a good exercise.

Thank you!

Best

Pablo

On Wed, Mar 9, 2022, 4:39 PM 'Dan Kortschak' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> On Wed, 2022-03-09 at 03:37 -0800, christoph...@gmail.com wrote:
> > I'm translating a scientific C program into Go that is doing some
> > 64bit floating point operations.
> >
> > In this process I check that the same input yields the same output.
> > Unfortunately they don't yield the same result, though the
> > computation is simple. It is as follow. I receive a 64bit integer
> > value.
> >
> > This value is converted to float64/double, and divided by 2^64.
> > The resulting number is multiplied by 1e8.
> >
> > With C I get 41 6E 84 FD 00 09 90 D7, with Go I get 41 6E 84 FD 00 09
> > E6 8E. The last 15bits are different. The computation is performed
> > with the same computer.
> >
> > Could it be that the C program is performing the computation with
> > long double (80 bit) precision and that Go is doing it with 64bit
> > precision ?
> >
> > Is there something I could do about it because that might be a red
> > flag for replacing the C program with a Go program.
>
> This is not very surprising depending on the algorithms that are being
> used/the problem that is being solved. Some problems are fundamentally
> difficult to solve exactly and the nature of floating point makes them
> sensitive to the precise set of operations used, intermediate rounding
> and the order of operations (even for operations that are commutative
> in theory). As Robert said, knowing the C compiler will be important,
> and I'd go further, knowing which platform you are building the Go
> program on can be important due to differences in how floating point
> operations are rendered into machine code by the compiler, or even how
> the processor orders apparently commutative operations.
>
> Assuming the values that you've pasted above are big endian, then the
> Go value is within a 1e12th of the value calculate by C (
> https://go.dev/play/p/dn7G2LI75RC). This is not terrible, and maybe
> that level of precision is all that can be promised by the algorithm
> (and believing digits smaller that 1e-12 is dangerous). Alternatively
> there is no fundamental limit at this point and there is a better more
> stable algorithm that you can use (though you are only four orders of
> magnitude from the machine epsilon
> https://en.wikipedia.org/wiki/Machine_epsilon, so be aware).
>
> Floats are tricky beasts and can easily trip people up. I would suggest
> that you read
> https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html (and
> the more friendly https://floating-point-gui.de/).
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/ee58b6e5ad163014b256d249e21c875307fecddb.camel%40kortschak.io
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAPxFe-vuCoHfQnZxXLaseYty7672ku0_a1ee3BB4LexOs_qKcA%40mail.gmail.com.


Re: [go-nuts] Possible float64 precision problem

2022-03-09 Thread 'Dan Kortschak' via golang-nuts
On Wed, 2022-03-09 at 03:37 -0800, christoph...@gmail.com wrote:
> I'm translating a scientific C program into Go that is doing some
> 64bit floating point operations.
>
> In this process I check that the same input yields the same output.
> Unfortunately they don't yield the same result, though the
> computation is simple. It is as follow. I receive a 64bit integer
> value.
>
> This value is converted to float64/double, and divided by 2^64.
> The resulting number is multiplied by 1e8.
>
> With C I get 41 6E 84 FD 00 09 90 D7, with Go I get 41 6E 84 FD 00 09
> E6 8E. The last 15bits are different. The computation is performed
> with the same computer.
>
> Could it be that the C program is performing the computation with
> long double (80 bit) precision and that Go is doing it with 64bit
> precision ?
>
> Is there something I could do about it because that might be a red
> flag for replacing the C program with a Go program.

This is not very surprising depending on the algorithms that are being
used/the problem that is being solved. Some problems are fundamentally
difficult to solve exactly and the nature of floating point makes them
sensitive to the precise set of operations used, intermediate rounding
and the order of operations (even for operations that are commutative
in theory). As Robert said, knowing the C compiler will be important,
and I'd go further, knowing which platform you are building the Go
program on can be important due to differences in how floating point
operations are rendered into machine code by the compiler, or even how
the processor orders apparently commutative operations.

Assuming the values that you've pasted above are big endian, then the
Go value is within a 1e12th of the value calculate by C (
https://go.dev/play/p/dn7G2LI75RC). This is not terrible, and maybe
that level of precision is all that can be promised by the algorithm
(and believing digits smaller that 1e-12 is dangerous). Alternatively
there is no fundamental limit at this point and there is a better more
stable algorithm that you can use (though you are only four orders of
magnitude from the machine epsilon
https://en.wikipedia.org/wiki/Machine_epsilon, so be aware).

Floats are tricky beasts and can easily trip people up. I would suggest
that you read
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html (and
the more friendly https://floating-point-gui.de/).



-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ee58b6e5ad163014b256d249e21c875307fecddb.camel%40kortschak.io.


[go-nuts] Possible float64 precision problem

2022-03-09 Thread christoph...@gmail.com
I'm translating a scientific C program into Go that is doing some 64bit 
floating point operations. 

In this process I check that the same input yields the same output. 
Unfortunately they don't yield the same result, though the computation is 
simple. It is as follow. I receive a 64bit integer value. 

This value is converted to float64/double, and divided by 2^64.
The resulting number is multiplied by 1e8. 

With C I get 41 6E 84 FD 00 09 90 D7, with Go I get 41 6E 84 FD 00 09 E6 
8E. The last 15bits are different. The computation is performed with the 
same computer.

Could it be that the C program is performing the computation with long 
double (80 bit) precision and that Go is doing it with 64bit precision ? 

Is there something I could do about it because that might be a red flag for 
replacing the C program with a Go program.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f9b7a823-e010-4c51-9491-6da865754dc2n%40googlegroups.com.