0

I'm learning to write apps in swift playground using swift, but I am very confused by the following issue. I wanted to simply write a fibonacci program to test it's capabilities, but it randomly crashes after a random amount of iterations. (8, 11, 55 etc.) Here's the code:

var num1 = 0, num2 = 1
for i in 0..<100{
    print(num1)
    var temp = num2
    num2 += num1
    num1 = temp
}

2 Answers2

1

This is an integer overflow problem when the next Fibonacci number (num2) becomes too large to represent as a signed 64-but integer. The crash seems random because the output from the program is buffered and not all the messages that have been printed will be visible yet. I tried adding a delay to try and remove the buffering and force output to appear:

var num1 = 0, num2 = 1
for i in 0..<100{
    print(i, num1)
    usleep(250_000)
    
    var temp = num2
    num2 += num1
    num1 = temp
}

In swift playgrounds on the iPad this reliably shows me up to number 91:

89 1779979416004714189
90 2880067194370816120
91 4660046610375530309

Since Int.Max is 9223372036854775807 and the code is printing num1, this means that num2 has already been set to 7540113804746346429 in the i==90 iteration. Before the code can print num1 for i==92 it will need to add 4660046610375530309 to num2 (in the i==91 iteration) and that will be too large for a signed 64-bit integer (12200160415121876738)

Geoff Hackworth
  • 2,673
  • 1
  • 16
  • 16
0

The issue with your implementation is that it will continue to print numbers in the sequence until it overflows the bounds of the data type being used to represent the numbers. Try this one.

var num1 = 0, num2 = 1
while num1 <= Int.max - num2 {
    print(num1)
    let temp = num2
    num2 += num1
    num1 = temp
}

This is a better solution for avoiding integer overflow.

func fibonacci(upTo n: Int) -> [Int] {
    guard n > 0 else {
        return []
    }
    var fib = [0, 1]
    while fib.last! < n {
        let nextFib = fib.last! + fib[fib.count - 2]
        guard nextFib <= n else {
            break
        }
        fib.append(nextFib)
    }
    return fib
}
iShox
  • 367
  • 2
  • 10