can anyone make this code better ?

76 views
Skip to first unread message

Aman Rana

unread,
Mar 16, 2015, 5:55:24 AM3/16/15
to swift-l...@googlegroups.com

wrote this program in Swift. I am a beginner and want to develop apps. Can anyone suggest ways to make this code better ?


class fibonacci {

    var num1 : Int = 0

    var num2 : Int = 1

    let maxLimit : Int = 90

    let limit : Int

    

    init(limit : Int = 20) {

        self.limit = limit

        calc()

    }

    

    func calc (counter : Int = 1) {

        if limit > maxLimit {

            println("Please enter number less than or equal to 90.")

        } else {

            if counter <= limit {

                if counter == 1 {

                    println(num1)

                } else if counter == 2 {

                    println(num2)

                } else {

                    let total = num1 + num2

                    println(total)

                    num1 = num2

                    num2 = total

                }

                calc(counter: counter+1)

            }

        }

    }

}


fibonacci(limit: 30)

Nevin Brackett-Rozinsky

unread,
Apr 15, 2015, 2:31:59 AM4/15/15
to swift-l...@googlegroups.com
If the goal is just to calculate Fibonacci numbers, then personally I’d go with something like this:

var fibDict = [0:0, 1:1, 2:1]

func fibonacci(n : Int) -> Int {
    if let r = fibDict[n] { return r }
    if n < 0 { return -1 }
    
    let a = fibonacci(n/2 + 1)
    let b = fibonacci((n-1)/2)
    
    let result : Int
    if n%2 == 0 { result = a*a - b*b }
    else        { result = a*a + b*b }
    
    fibDict[n] = result;
    return result
}

This works through n=92, beyond that the result exceeds Int.max. Making everything a UInt lets it work for n=93, hardly worth the effort. But making the values be NSDecimalNumber objects? Now that lets it go all the way up to n=793, and still blazing fast!

import Foundation   // or Cocoa

var fibDecDict : [Int : NSDecimalNumber] = [0:0, 1:1, 2:1]

func fibonacciDecimalNumber(n : Int) -> NSDecimalNumber {
    if let r = fibDecDict[n] { return r }
    if n < 0 { return NSDecimalNumber.notANumber() }
    
    let a = fibonacciDecimalNumber(n/2 + 1)
    let a2 = a.decimalNumberByMultiplyingBy(a)
    
    let b = fibonacciDecimalNumber((n-1)/2)
    let b2 = b.decimalNumberByMultiplyingBy(b)
    
    let result : NSDecimalNumber
    if n%2 == 0 { result = a2.decimalNumberBySubtracting(b2) }
    else        { result = a2.decimalNumberByAdding(b2) }
    
    fibDecDict[n] = result
    return result
}

Nevin Brackett-Rozinsky

unread,
Apr 15, 2015, 3:11:19 PM4/15/15
to swift-l...@googlegroups.com
Turns out using Double lets it go all the way to n=1476, still as fast as ever:

var fibDblDict : [Int : Double] = [0:0.0, 1:1.0, 2:1.0]

func fibonacciDouble(n : Int) -> Double {
    if let r = fibDblDict[n] { return r }
    if n < 0 { return Double.NaN }
    
    let a = fibonacciDouble(n/2 + 1)
    let b = fibonacciDouble((n-1)/2)
    
    let result : Double
    if n%2 == 0 { result = a*a - b*b }
    else        { result = a*a + b*b }
    
    fibDblDict[n] = result
    return result
}

Jeremy Pereira

unread,
Apr 16, 2015, 11:37:02 AM4/16/15
to Nevin Brackett-Rozinsky, swift-l...@googlegroups.com

> On 15 Apr 2015, at 20:11, Nevin Brackett-Rozinsky <nevin.brack...@gmail.com> wrote:
>
> Turns out using Double lets it go all the way to n=1476, still as fast as ever:

Probably not. A Double has fewer bits of precision than a 64 bit integer on account of being the same size and needing some space for the exponent. Therefore, you will be losing bits with the larger values of n.

>
> var fibDblDict : [Int : Double] = [0:0.0, 1:1.0, 2:1.0]
>
> func fibonacciDouble(n : Int) -> Double {
> if let r = fibDblDict[n] { return r }
> if n < 0 { return Double.NaN }
>
> let a = fibonacciDouble(n/2 + 1)
> let b = fibonacciDouble((n-1)/2)
>
> let result : Double
> if n%2 == 0 { result = a*a - b*b }
> else { result = a*a + b*b }
>
> fibDblDict[n] = result
> return result
> }
>
> --
> You received this message because you are subscribed to the Google Groups "Swift Language" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to swift-languag...@googlegroups.com.
> To post to this group, send email to swift-l...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/918e5c36-c1d3-457d-b60e-3fba768b7459%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Nevin Brackett-Rozinsky

unread,
Apr 16, 2015, 3:02:01 PM4/16/15
to swift-l...@googlegroups.com

On Thursday, April 16, 2015 at 11:37:02 AM UTC-4, Jeremy Pereira wrote:

A Double has fewer bits of precision than a 64 bit integer on account of being the same size and needing some space for the exponent.  Therefore, you will be losing bits with the larger values of n.
 
Right, but it’s completely correct through n=78, and beyond that it’s accurate to essentially the precision of a Double. Compare it against an arbitrary-precision system, eg. Wolfram Alpha.
Reply all
Reply to author
Forward
0 new messages