Checking if a double value is an integer - Swift

SwiftIntDouble

Swift Problem Overview


I need to check if a double-defined variable is convertible to Int without losing its value. This doesn't work because they are of different types:

if self.value == Int(self.value)

where self.value is a double.

Swift Solutions


Solution 1 - Swift

Try 'flooring' the double value then checking if it is unchanged:

let dbl = 2.0
let isInteger = floor(dbl) == dbl // true

Fails if it is not an integer

let dbl = 2.4
let isInteger = floor(dbl) == dbl // false

Solution 2 - Swift

check if % 1 is zero:

Swift 3:

let dbl = 2.0
let isInteger = dbl.truncatingRemainder(dividingBy: 1) == 0

Swift 2:

let dbl = 2.0
let isInteger = dbl % 1 == 0

Solution 3 - Swift

Swift 3

if dbl.truncatingRemainder(dividingBy: 1) == 0 {
  //it's an integer
}

Solution 4 - Swift

There is now an Int(exactly:) initializer that will tell you this directly without the problem of out-of-range whole numbers.

if Int(exactly: self) != nil { ... }

This will only return a non-nil value if the result can actually be stored in Int exactly. There are many Double values that are "integers" but will not fit in an Int. (See MartinR's comment on the accepted answer.)

Solution 5 - Swift

A small extension to check for this:

extension FloatingPoint {
    var isInt: Bool {
        return floor(self) == self
    }
}

Then just do

let anInt = 1.isInt
let nonInt = 3.142.isInt

Solution 6 - Swift

Simple Solution

I suggest converting the value to Int then to Double and checking the new value

if value == Double(Int(value)) {
// The value doesn't have decimal part. ex: 6.0

} else {
//  The value has decimal part. ex: 6.3

}

Solution 7 - Swift

The Swifty way:

let cals = [2.5, 2.0]

let r = cals.map{ Int(exactly: $0) == nil ?  "\($0)" : "\(Int($0))" }

r // ["2.5", "2"]

Hide away in an extension:

extension Array where Element == Double {
    var orExactly: [String] {
        map{ Int(exactly: $0) == nil ?  "\($0)" : "\(Int($0))" }
    }
}

cals.orExactly

Solution 8 - Swift

Using mod (%) won't work anymore.

You can now use:

let dbl = 2.0
let isInteger = dbl.truncatingRemainder(dividingBy: 1.0) == 0.0

Solution 9 - Swift

How about converting the Double to an Int (which will cut off decimals), then back to a Double, then comparing this to the original Double? For example:

var dbl:Double = 22/3
dbl == Double(Int(dbl))
// false: dbl = 7.33333... Double(Int(dbl)) = 7.0

dbl = 25
dbl == Double(Int(dbl))
// true: dbl = 25.0, Double(Int(dbl)) = 25.0

Solution 10 - Swift

BECAREFUL.

truncatingRemainder(dividingBy:) can be tricky. See below:

Swift 4:

//case 1
let reminder = (4.1 * 100).truncatingRemainder(dividingBy: 1.0)

//case 2
let reminder2 = (410).truncatingRemainder(dividingBy: 1.0)

// reminder = 0.9999999999999432
// reminder2 = 0 

Solution 11 - Swift

Using @ColinE answer, I build an extension that handles when the Double cannot be converted to Int and another function that returns the Int:

extension Double {
    
    func isInt() -> Bool {
        guard Double(Int.min) <= self && self <= Double(Int.max) else {
            return false
        }
        
        return floor(self) == self
    }
    
    func toInt() -> Int? {
        guard Double(Int.min) <= self && self <= Double(Int.max) else {
            return nil
        }
        
        return Int(self)
    }
}

I hope this helps someone,

Xavi

Solution 12 - Swift

extension FloatingPoint {
    var isWholeNumber: Bool { isNormal ? self == rounded() : isZero }
}

let double = 3.0    
double.isWholeNumber        // true
print(3.15.isWholeNumber)   // false

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYoussef MoawadView Question on Stackoverflow
Solution 1 - SwiftColinEView Answer on Stackoverflow
Solution 2 - SwiftrintaroView Answer on Stackoverflow
Solution 3 - SwiftWilliam T.View Answer on Stackoverflow
Solution 4 - SwiftRob NapierView Answer on Stackoverflow
Solution 5 - SwiftCiprian RarauView Answer on Stackoverflow
Solution 6 - SwiftMusa almatriView Answer on Stackoverflow
Solution 7 - SwiftsmileBotView Answer on Stackoverflow
Solution 8 - SwiftChadView Answer on Stackoverflow
Solution 9 - SwiftGallaugherView Answer on Stackoverflow
Solution 10 - SwiftCocodyRockStarView Answer on Stackoverflow
Solution 11 - SwiftXMEView Answer on Stackoverflow
Solution 12 - SwiftLeo DabusView Answer on Stackoverflow