0

Is there a way to determine if a float has non zero decimal values? I'd like to avoid a string conversion then splitting on any decimal. But not sure if there is some other way.

4thSpace
  • 43,672
  • 97
  • 296
  • 475

2 Answers2

1

You can't.

Floating point variables (both Float and Double) store values with a limited precesion. Very rarely will a number will be stored as .000....

See Is floating point math broken?

The work around:

First, determine an epsilon value you deem to be "as far from .000... as a number can be for me to still consider it 'whole'". This number will depend on your problem domain. Suppose I values within .001 are acceptably "whole"

Secondly, determine what the closest whole number by rounding it.

Finally, subtract the original value from its rounded counterpart, and check if the difference is less within the epsilon value.

import Foundation

extension Double {
    private static var epsilon = 0.0001

    var isWhole: Bool { return abs(self - round(self)) < Double.epsilon }
}

let input = 1.0
print(input.isWhole)

This is very similar to the recommended technique for comparing equality of two Float/Double values.

Community
  • 1
  • 1
Alexander
  • 59,041
  • 12
  • 98
  • 151
0

In Swift 3.0

Since Swift 3.0 is fast approaching, I'll include an answer for it, even if the question specifically covers Swift 2.

In Swift 3.0 Enhanced Floating Point Protocols has been implemented, making it easier to work with floating point arithmetics. We can, e.g. use the isEqual method, which implements the IEEE 754 equality predicate, for comparing two floating point numbers

import Foundation // for access to round function

extension Double {
    var isAsGoodAsIntegerValuedAsItGets: Bool {
        return isEqual(to: round(self))
    }
}

var input = 1.01
print(input.isAsGoodAsIntegerValuedAsItGets) // false

input = 1
print(input.isAsGoodAsIntegerValuedAsItGets) // true

/* increase to least representable value that compares 
   greater than current `self` */
input = input.nextUp 
print(input.isAsGoodAsIntegerValuedAsItGets) // false

/* decrease to the greatest representable value that 
   compares less than current `self` */
input = input.nextDown
print(input.isAsGoodAsIntegerValuedAsItGets) // true
Community
  • 1
  • 1
dfrib
  • 70,367
  • 12
  • 127
  • 192