* Yuval Lifshitz <yuva...@gmail.com> [180430 02:02]:
> It seems like go and C++ are doing something different regarding floating 
> point arithmetic, but I cannot say one is better than the other. It is just 
> the that C++ consistently overshoots (hence truncation work), and go 
> consistently undershoots (this is why rounding is needed). For example, in 
> C++:
> 
> F(59) = 956722026041.002
> 
> And in go, it is:
> 
> F(59) = 956722026040.999878

/* aside - this doesn't seem relevant to this problem except perhaps
 * the implementation of math.Pow, but...

The 8087 and successor FPUs (e.g. amd64 class processors) have an 80-bit
extended precision format which is used for all calculations.  More than
a couple decades ago, when I was working on implementation of floating
point in an APL interpreter (written in C, C++, asm), the IEEE 754
standard did not specify how compilers should handle precision of
intermediate results, and the compiler we were using would only convert
from 80-bit to 64-bit when it needed to store a result back into memory.
This could easily give different results depending on how the floating
point expression was broken up.  E.g. a = (b + c) - d could give a
different result than a = b + c; a = a - d.

The standard has, since then, attempted to address this, but I have not
studied this at all, so I don't know what is expected of C or Go.

*/

Back to your specific problem:

Go:  psi = -0.61803398874989490
C++: psi = -0.61803398874989479

Go:  math.Pow(math.Phi, float64(33)) = 7.88119600000012666e+06
C++:                    pow(phi, 33) = 7.88119600000013597e+06

And using hand-typed constants:

Go:  math.Pow(1.61803398874989490, 33.0) = 7.88119600000012666e+06
C++:      pow(1.61803398874989490, 33.0) = 7.88119600000013597e+06

So indeed there is a difference between math.Pow in Go and pow in C++.
I would say to file an issue.  I have no idea which answer is closer to
correct, but using math/big and multiplying 1.61803398874989490 by
itself 33 times with a result precision of 80, I get
7.88119600000013562e+06.

Note:  in Go, math.Phi is an untyped constant with precision greater
than float64.  Adding  var phi float64 = math.Phi  and replacing
math.Phi everywhere else with phi did not change anything except the
value of psi (which then matched the C++ value).  The C++ version of psi
is definitely farther from the "true" value, but as Michael said, the
error in pow(psi, n) is swamped by the value of pow(phi, n).

...Marvin

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to