I'm printing out a number whose value I don't know. In most cases the number is whole or has a trailing .5. In some cases the number ends in .25 or .75, and very rarely the number goes to the thousandths place. How do I specifically detect that last case? Right now my code detects a whole number (0 decimal places), exactly .5 (1 decimal), and then reverts to 2 decimal spots in all other scenarios, but I need to go to 3 when it calls for that.
class func getFormattedNumber(number: Float) -> NSString {
var formattedNumber = NSString()
// Use the absolute value so it works even if number is negative
if (abs(number % 2) == 0) || (abs(number % 2) == 1) { // Whole number, even or odd
formattedNumber = NSString(format: "%.0f", number)
}
else if (abs(number % 2) == 0.5) || (abs(number % 2) == 1.5) {
formattedNumber = NSString(format: "%.1f", number)
}
else {
formattedNumber = NSString(format: "%.2f", number)
}
return formattedNumber
}
A Float
uses a binary (IEEE 754) representation and cannot represent
all decimal fractions precisely. For example,
let x : Float = 123.456
stores in x
the bytes 42f6e979
, which is approximately
123.45600128173828
. So does x
have 3 or 14 fractional digits?
You can use NSNumberFormatter
if you specify a maximum number
of decimal digits that should be presented:
let fmt = NSNumberFormatter()
fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX")
fmt.maximumFractionDigits = 3
fmt.minimumFractionDigits = 0
println(fmt.stringFromNumber(123)!) // 123
println(fmt.stringFromNumber(123.4)!) // 123.4
println(fmt.stringFromNumber(123.45)!) // 123.45
println(fmt.stringFromNumber(123.456)!) // 123.456
println(fmt.stringFromNumber(123.4567)!) // 123.457
Swift 3/4 update:
let fmt = NumberFormatter()
fmt.locale = Locale(identifier: "en_US_POSIX")
fmt.maximumFractionDigits = 3
fmt.minimumFractionDigits = 0
print(fmt.string(for: 123.456)!) // 123.456
You can use %g
to suppress trailing zeros. Then I think you do not need to go through the business of determining the number of places. Eg -
var num1:Double = 5.5
var x = String(format: "%g", num1) // "5.5"
var num2:Double = 5.75
var x = String(format: "%g", num2) // "5.75"
Or this variation where the number of places is specified. Eg -
var num3:Double = 5.123456789
var x = String(format: "%.5g", num3) // "5.1235"
My 2 cents ;) Swift 3 ready
Rounds the floating number and strips the trailing zeros to the required minimum/maximum fraction digits.
extension Double {
func toString(minimumFractionDigits: Int = 0, maximumFractionDigits: Int = 2) -> String {
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.minimumFractionDigits = minimumFractionDigits
formatter.maximumFractionDigits = maximumFractionDigits
return formatter.string(from: self as NSNumber)!
}
}
Usage:
Double(394.239).toString() // Output: 394.24
Double(394.239).toString(maximumFractionDigits: 1) // Output: 394.2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With