yes. truncation and round-up are important differences between your c/c++
code and the go code.

On Sun, Apr 29, 2018 at 12:08 AM Yuval Lifshitz <yuva...@gmail.com> wrote:

> (1) I understand the issue of limited precision, this is why I did not try
> anything above F(59) But my concern was not the difference between algebra
> and the go implementation it was the different results I got with the C/C++
> implementation (gcc 7.3.1):
>
> #include <math.h>
>
> const double sqrt_5 = sqrt(5.0);
> const double phi = (1.0 + sqrt_5)/2.0;
> const double psi = -1.0/phi;
>
> // find the nth fibonacci number based on Binet's formula
> // see here:
> https://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression
> unsigned long long fibonacci(unsigned n)
> {
>     return (unsigned long long)((pow(phi, n) - pow(psi, n))/sqrt_5);
> }
>
>
> (2) Thanks for the fix, work well for the go implementation. However, if i
> try to apply it on the C++ one (where there is no rounding), it makes some
> of the tests fails. So, I guess that without rounding, the psi part is
> needed
>
> (3) Is there a way to print the map ordered (didn't see that in your
> snippet)?
>
> (4) Wanted to compare "double" in C++ to "float64" in go. As they should
> consume same amount of memory, have similar algorithms etc. but good to
> know about the "big" package in go
>
> (5) Thanks for the reference. interesting read
>
> On Saturday, 28 April 2018 00:57:42 UTC+3, Michael Jones wrote:
>>
>> Yuval,
>>
>> There are fundamental issues here.
>>
>> 1. That equation (de Moivre, Binet) is from the algebra of ideal numbers.
>> Numbers of infinite precision. Not the realm of computer arithmetic. It
>> works fine with double precision (go: float64, c/c++: double) up to F(75)
>> but must fail for F(76) due to the limited precision of 64-bit floating
>> point and has nothing to do with language.
>>
>> F(76) = 3416454622906707 but the best we can do in 64 bits is
>> 3416454622906706 even with a Pow() function good to +/-1 least significant
>> bit.
>>
>> 2. Another difference between algebra and computer arithmetic
>> (well...actually about the floor function) is that one of your two power
>> terms is not needed. Psi < 1 so Psi^N is pretty small, so small, that it
>> never changes the value of the rounded result. So you can just evaluate:
>>
>> return round(math.Pow(math.Phi, float_n) / sqrt_5)
>>
>> 3. Using a map in your test is not wrong, but it means that the tests
>> will be executed in a random order, which makes the printed errors a little
>> less clear.
>>
>> celeste:fib mtj$ go test -v
>> === RUN   Test_fibonacci
>> --- FAIL: Test_fibonacci (0.00s)
>> fib_test.go:104: 82 : Expected 61305790721611591 got 61305790721611584
>> fib_test.go:104: 84 : Expected 160500643816367088 got 160500643816367040
>> fib_test.go:104: 81 : Expected 37889062373143906 got 37889062373143896
>> fib_test.go:104: 87 : Expected 679891637638612258 got 679891637638612096
>> fib_test.go:104: 88 : Expected 1100087778366101931 got 1100087778366101632
>> fib_test.go:104: 83 : Expected 99194853094755497 got 99194853094755488
>> fib_test.go:104: 77 : Expected 5527939700884757 got 5527939700884756
>> fib_test.go:104: 86 : Expected 420196140727489673 got 420196140727489600
>> fib_test.go:104: 90 : Expected 2880067194370816120 got 2880067194370815488
>> fib_test.go:104: 91 : Expected 4660046610375530309 got 4660046610375529472
>> fib_test.go:104: 92 : Expected 7540113804746346429 got 7540113804746344448
>> fib_test.go:104: 76 : Expected 3416454622906707 got 3416454622906706
>> fib_test.go:104: 85 : Expected 259695496911122585 got 259695496911122528
>> fib_test.go:104: 89 : Expected 1779979416004714189 got 1779979416004713728
>> fib_test.go:104: 79 : Expected 14472334024676221 got 14472334024676218
>> fib_test.go:104: 80 : Expected 23416728348467685 got 23416728348467676
>> FAIL
>> exit status 1
>> FAIL fib 0.003s
>>
>> updated fib.go: https://play.golang.org/p/N-8lmjrMYAq
>> update fib_test.go: https://play.golang.org/p/FPuN58m1VVs
>>
>> 4. Plenty of ways to do this computation in Go using 64-bit integers, or
>> big floats, or big ints.
>>
>> 5. Plenty of algorithms, some quite fascinating!
>> https://ir.library.oregonstate.edu/downloads/t435gg51w
>> <https://www.google.com/url?q=https%3A%2F%2Fir.library.oregonstate.edu%2Fdownloads%2Ft435gg51w&sa=D&sntz=1&usg=AFQjCNFeFx9ebd-m_yzIjw4H29wdLpzmVw>
>>
>>
>> On Thu, Apr 26, 2018 at 10:22 AM, Ian Lance Taylor <ia...@golang.org>
>> wrote:
>>
>>> On Thu, Apr 26, 2018 at 1:17 AM, Yuval Lifshitz <yuv...@gmail.com>
>>> wrote:
>>> >
>>> > I ran into the following issue when started playing with go. Had the
>>> > following small program to calculate Fibonacci numbers using the closed
>>> > form:
>>> >
>>> > package "fib"
>>> >
>>> > import "math"
>>> >
>>> > var sqrt_5 = math.Sqrt(5.0)
>>> > var psi = -1.0/math.Phi
>>> >
>>> > // had to add this to solve accuracy issue
>>> > func round(x float64) uint64 {
>>> >     return uint64(math.Floor(x + 0.5))
>>> > }
>>> >
>>> > // find the nth fibonacci number based on Binet's formula
>>> > // see here:
>>> > https://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression
>>> > func fibonacci(n uint) uint64 {
>>> >     float_n := float64(n)
>>> >     return round((math.Pow(math.Phi, float_n) - math.Pow(psi,
>>> > float_n))/sqrt_5)
>>> > }
>>> >
>>> >
>>> > When I first tried without doing the "rounding" I did not get whole
>>> numbers
>>> > as the output (similar program in C++ gave whole numbers without
>>> rounding).
>>> > Following test is failing without the call to "round()":
>>> >
>>> > package "fib"
>>> >
>>> > import "testing"
>>> >
>>> > var results = map[uint]uint64 {
>>> >     0: 0,
>>> >     2: 1,
>>> >     10: 55,
>>> >     14: 377,
>>> >     20: 6765,
>>> >     29: 514229,
>>> >     33: 3524578,
>>> >     59: 956722026041,
>>> > }
>>> >
>>> > func Test_fibonacci(t *testing.T) {
>>> >     for arg, expected := range results {
>>> >         actual := fibonacci(arg)
>>> >         if actual != expected {
>>> >             t.Error("Expected", expected, "got", actual)
>>> >         }
>>> >     }
>>> > }
>>> >
>>> >
>>> >
>>> > Are there known accuracy issues with floating points in go?
>>>
>>> No.
>>>
>>> I suggest that you show us your C code.  Thanks.
>>>
>>> Ian
>>>
>>> --
>>> 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.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> --
>> Michael T. Jones
>> michae...@gmail.com
>>
> --
> 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.
>


-- 
Michael T. Jones
michael.jo...@gmail.com

-- 
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