mgChristopher
mgChristopher

Reputation: 375

Testing if a Decimal is a whole number in Swift

Using Swift 3.

I am finding a lot of strange solutions online for checking if a Decimal object is a whole number. Everything feels far more complicated then it needs to be.

Here is my solution:

extension Decimal {
    var isWholeNumber: Bool {
        return self.exponent == 1
    }
}

In my tests this works. My question is am I missing something obvious?

Upvotes: 7

Views: 2967

Answers (4)

Human Friend
Human Friend

Reputation: 175

I'm pretty new to Swift but I'm comparing the input to a rounded input:

let input = 2.9

round(input) == input
        3        2.9

Upvotes: 0

Giuseppe Mazzilli
Giuseppe Mazzilli

Reputation: 502

I'm not sure can works in all cases but that maybe a more coincise option

extension Decimal {

    static var decimalSeparator: String { return NumberFormatter().decimalSeparator }

    var isFraction: Bool {
        return self.description.contains(Decimal.decimalSeparator)
    }

    var isWhole: Bool {
        return !isFraction
    }

}

Upvotes: -2

Martin R
Martin R

Reputation: 540075

Here is a translation of the Objective-C solution in Check if NSDecimalNumber is whole number to Swift:

extension Decimal {
    var isWholeNumber: Bool {
        if isZero { return true }
        if !isNormal { return false }
        var myself = self
        var rounded = Decimal()
        NSDecimalRound(&rounded, &myself, 0, .plain)
        return self == rounded
    }
}

print(Decimal(string: "1234.0")!.isWholeNumber) // true
print(Decimal(string: "1234.5")!.isWholeNumber) // false

This works even if the mantissa is not minimal (or the exponent not maximal), such as 100 * 10-1. Example:

let z = Decimal(_exponent: -1, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0,
                _mantissa: (100, 0, 0, 0, 0, 0, 0, 0))

print(z) // 10.0
print(z.exponent) // -1
print(z.isWholeNumber) // true

Upvotes: 5

mgChristopher
mgChristopher

Reputation: 375

Thanks for the comments! Here is what I am using now.

extension Decimal {
    var isWholeNumber: Bool { 
        return self.isZero || (self.isNormal && self.exponent >= 0) 
    }
}

Upvotes: 8

Related Questions