in C/C++ (at least on my system) "float" 4 has 4 bytes (32bits) and double 
has 8 bytes (64bits). according to this: https://golang.org/pkg/math/ its 
is the same thing with go.

On Sunday, 29 April 2018 22:27:23 UTC+3, Louki Sumirniy wrote:
>
> I could be wrong but float64 is 'float' and 'double float' is float128. I 
> dunno, I have not tinkered with these imprecise math types. That's just, 
> essentially, what they were back in the olden days, like 20 years ago. 64 
> bit was basic float, 128 was double. I have been out of the loop for way 
> too long on these things (and I am not a fan of floats anyway, give me some 
> fixed precision pls).
>
> On Sunday, 29 April 2018 10:08:15 UTC+3, Yuval Lifshitz 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.

Reply via email to