Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to implement fast double Fibonacci algorithm as described
here
:
// Fast doubling Fibonacci algorithm
package main
import "fmt"
// (Public) Returns F(n).
func fibonacci(n int) int {
if n < 0 {
panic("Negative arguments not implemented")
fst, _ := fib(n)
return fst
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (int, int) {
if n == 0 {
return 0, 1
a, b := fib(n / 2)
c := a * (b*2 - a)
d := a*a + b*b
if n%2 == 0 {
return c, d
} else {
return d, c + d
func main() {
fmt.Println(fibonacci(13))
fmt.Println(fibonacci(14))
This works fine for small numbers; however, when the input number get larger, the program returns a wrong result. So I tried to use bigInt from math/big package:
// Fast doubling Fibonacci algorithm
package main
import (
"fmt"
"math/big"
// (Public) Returns F(n).
func fibonacci(n int) big.Int {
if n < 0 {
panic("Negative arguments not implemented")
fst, _ := fib(n)
return fst
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (big.Int, big.Int) {
if n == 0 {
return big.Int(0), big.Int(1)
a, b := fib(n / 2)
c := a * (b*2 - a)
d := a*a + b*b
if n%2 == 0 {
return c, d
} else {
return d, c + d
func main() {
fmt.Println(fibonacci(123))
fmt.Println(fibonacci(124))
However, go build complains that
cannot convert 0 (type int) to type big.Int
How to mitigate this problem?
Use big.NewInt() instead of big.Int(). big.Int() is just type casting.
You need to check out documentation of big package
You should mostly use methods with form func (z *T) Binary(x, y *T) *T // z = x op y
To multiply 2 arguments you need to provide result variable, after it call Mul method. So, for example, to get result of 2*2 you need to:
big.NewInt(0).Mul(big.NewInt(2), big.NewInt(2))
You can try working example on the Go playground
Also you can create extension functions like:
func Mul(x, y *big.Int) *big.Int {
return big.NewInt(0).Mul(x, y)
To make code more readable:
// Fast doubling Fibonacci algorithm
package main
import (
"fmt"
"math/big"
// (Public) Returns F(n).
func fibonacci(n int) *big.Int {
if n < 0 {
panic("Negative arguments not implemented")
fst, _ := fib(n)
return fst
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (*big.Int, *big.Int) {
if n == 0 {
return big.NewInt(0), big.NewInt(1)
a, b := fib(n / 2)
c := Mul(a, Sub(Mul(b, big.NewInt(2)), a))
d := Add(Mul(a, a), Mul(b, b))
if n%2 == 0 {
return c, d
} else {
return d, Add(c, d)
func main() {
fmt.Println(fibonacci(123))
fmt.Println(fibonacci(124))
func Mul(x, y *big.Int) *big.Int {
return big.NewInt(0).Mul(x, y)
func Sub(x, y *big.Int) *big.Int {
return big.NewInt(0).Sub(x, y)
func Add(x, y *big.Int) *big.Int {
return big.NewInt(0).Add(x, y)
Try it on the Go playground
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.