Int Overflow. Big Int Solves It

What happens when you add 1 to the biggest number in math? There will be new the biggest number. Yet, what happens when you add 1 to the biggest number in Swift? Yes… crash happens.

So what is the biggest integer number we can keep in a variable in Swift? Million? Billion? Trillion? It is UInt64 with value 18.446.744.073.709.551.615. How much? It’s eighteen quintillions, four hundred forty-six quadrillion, seven hundred forty-four trillion, seventy-three billion, seven hundred nine million, five hundred fifty-one thousand, six hundred fifteen.

If UInt64 isn’t big enough it’s better to think it over but sometimes is too small. To keep bigger we need to store it using String. String can be as big as we want. Of course, we have memory limits.

BigInt In Code

We will create struct (or class, one of differences) with one String variable.

struct BigInt {
    var value: String = “”
    init(value: String) {
        self.value = value
    }
}

let bigInt = BigInt(value: “18446744073709551616”)
print(bigInt)

OUTPUT

BigInt(value: “18446744073709551616”)

It looks good but what can we do with this number? Nothing because it’s String and we can’t add or subtract a number from it. However, we can overload operator and create our own addition.

static func +(lhs: BigInt, rhs: BigInt) -> BigInt {
    let leftReversed: String = String(lhs.value.reversed())
    let rightReversed: String = String(rhs.value.reversed())
    var longerNumber = rightReversed
    var result: String = “”
    var isLeftShorter: Bool = true
    var length: Int = rightReversed.count
    if rightReversed.count < leftReversed.count {
        isLeftShorter = false
        length = leftReversed.count
        longerNumber = leftReversed
    }
    var buffor: Int = 0

    for i in 0..<length {
        let index = longerNumber.index(longerNumber.startIndex, offsetBy: i)
        var left: Int = 0
        var right: Int = 0
        
        if index < leftReversed.endIndex {
        
        left = Int(String(leftReversed[index])) ?? 0
        }
        
if index < rightReversed.endIndex {
        
        right = Int(String(rightReversed[index])) ?? 0
        }

        var sum = buffor + left + right
        buffor = 0
        if sum > 9 {
            buffor = sum /
10
            sum = sum %
10
        }
            result.
append(String(sum))
        }


     if isLeftShorter && rightReversed.count != length {
        
let index = rightReversed.index(rightReversed.startIndex, offsetBy: length)
        
let right: Int = Int(String(rightReversed[index]))!
        result.
append(String(right + buffor))
        result += rightReversed.
suffix(rightReversed.count – length – 1)
    }
else if !isLeftShorter && leftReversed.count != length {
        
let index = leftReversed.index(leftReversed.startIndex, offsetBy: length)
        
let left: Int = Int(String(leftReversed[index]))!
        result.
append(String(left + buffor))
        result += leftReversed.
suffix(leftReversed.count – length – 1)
    }
else if buffor > 0 {
        result.
append(String(buffor))
    }

    
return BigInt(value: String(result.reversed()))
}

Now, we can add two BigInt.

UPDATE: Thank CK for finding error! 🙂