Count Number of Decimal Places in a Float (Or Decimal) in Swift

Count number of decimal places in a Float (or Decimal) in Swift

Doing this with Decimal is fairly straightforward, provided you correctly create your Decimal. Decimals are stored as significand * 10^exponent. significand is normalized to the smallest integer possible. So for 1230, the significand is 123 and the exponent is 1. For 1.23 the significand is also 123 and the exponent is -2. That leads us to:

extension Decimal {
var significantFractionalDecimalDigits: Int {
return max(-exponent, 0)
}
}

However, you must be very careful constructing your Decimal. If you construct it from a Double, you will already have applied binary rounding errors. So for example:

let n = Decimal(0.111) // 0.11100000000000002048 because you passed a Double
n.significantFractionalDecimalDigits // 20

vs.

let n = Decimal(string: "0.111")!
n.significantFractionalDecimalDigits // 3 what you meant

Keep in mind of course that Decimal has a maximum number of significant digits, so it may still apply rounding.

let n = Decimal(string: "12345678901235678901234567890.1234567890123456789")!
n.significantFractionalDecimalDigits // 9 ("should" be 19)

And if you're walking down this road at all, you really must read the Floating Point Guide and the canonical StackOverflow question: Is floating point math broken?

Count amount of decimal places (Swift)

Try:

let s1 = String(format: "%.19g", 1.2345) // 1.2345

Not sure if swift printf supports '%g' though.

Edit: the 19 is based on the precision of a double, to display all (nonzero) digits, but not get ...0001 at the end. '%g' is the printf format specifier for 'natural' representation of floating point numbers.

Rounding a double value to x number of decimal places in swift

You can use Swift's round function to accomplish this.

To round a Double with 3 digits precision, first multiply it by 1000, round it and divide the rounded result by 1000:

let x = 1.23556789
let y = Double(round(1000 * x) / 1000)
print(y) /// 1.236

Unlike any kind of printf(...) or String(format: ...) solutions, the result of this operation is still of type Double.

EDIT:

Regarding the comments that it sometimes does not work, please read this: What Every Programmer Should Know About Floating-Point Arithmetic

Only show my float number to a certain decimal place - Swift

Use a NumberFormatter (have a look here)

let bmi:Float = (((textfieldInt! * 2.204623) * 0.5) / 1500) * textfield2Int!

let formatter = NumberFormatter()

//Set the min and max number of digits to your liking, make them equal if you want an exact number of digits
formatter.minimumFractionDigits = 1
formatter.maximumFractionDigits = 3

self.total2.text = formatter.string(from: NSNumber(value: bmi)) + " kcal"

How do I extract any number of digits after the decimal point of a Float and convert it to a String in Swift?

You can specify the number of decimal digits, say N, in your format specifier as %.Nf, e.g., for 5 decimal digits, %.5f.

let temp: Float = 3.511054256
let aStr = String(format: "%.5f", temp).componentsSeparatedByString(".").last ?? "Unexpected"
print(aStr) // 51105

Alternatively, for a more dynamic usage, make use of an NSNumberFormatter:

/* Use NSNumberFormatter to extract specific number
of decimal digits from your float */
func getFractionDigitsFrom(num: Float, inout withFormatter f: NSNumberFormatter,
forNumDigits numDigits: Int) -> String {
f.maximumFractionDigits = numDigits
f.minimumFractionDigits = numDigits
let localeDecSep = f.decimalSeparator
return f.stringFromNumber(num)?.componentsSeparatedByString(localeDecSep).last ?? "Unexpected"
}

/* Example usage */
var temp: Float = 3.511054256
var formatter = NSNumberFormatter()
let aStr = getFractionDigitsFrom(temp, withFormatter: &formatter, forNumDigits: 5)
print(aStr) // 51105

Note that both solutions above will perform rounding; e.g., if var temp: Float = 3.519, then asking for 2 decimal digits will produce "52". If you really intend to treat your float temp purely as a String (with no rounding whatsoever), you could solve this using just String methods, e.g.

/* Just treat input as a string with known format rather than a number */
func getFractionDigitsFrom(num: Float, forNumDigits numDigits: Int) -> String {
guard let foo = String(temp).componentsSeparatedByString(".").last
where foo.characters.count >= numDigits else {
return "Invalid input" // or return nil, for '-> String?' return
}
return foo.substringWithRange(foo.startIndex..<foo.startIndex.advancedBy(numDigits))
}

/* Example usage */
let temp: Float = 3.5199
let aStr = getFractionDigitsFrom(temp, forNumDigits: 2) // 51

Round up double to 2 decimal places

Use a format string to round up to two decimal places and convert the double to a String:

let currentRatio = Double (rxCurrentTextField.text!)! / Double (txCurrentTextField.text!)!
railRatioLabelField.text! = String(format: "%.2f", currentRatio)

Example:

let myDouble = 3.141
let doubleStr = String(format: "%.2f", myDouble) // "3.14"

If you want to round up your last decimal place, you could do something like this (thanks Phoen1xUK):

let myDouble = 3.141
let doubleStr = String(format: "%.2f", ceil(myDouble*100)/100) // "3.15"

Rounding a double to 2 decimal places in Swift, XCode 12

You could do it directly inside Text with the help of string interpolation:

struct ContentView: View {
let decimalNumber = 12.939010

var body: some View {
Text("\(decimalNumber, specifier: "%.2f")")//displays 12.94
}
}

Check if number is decimal with swift

If you round the number down (which you can do by using the floor function), and then subtract it from the original number, you will get the difference between the two.

if (number - floor(number) > 0.000001) { // 0.000001 can be changed depending on the level of precision you need
// decimal
}

Edit --

My original answer recommended calculating the difference between the number and its floored equivalent to see if there were any units after the decimal points. However, as later described, there may be a rounding error which causes the representation of a value in memory to be slightly different than what it's actually meant to be.

For example, 3.0 could be represented as 3.00000000000001, and therefore the number - floor(number) > 0 would return true, even though it should've theoretically returned false as the offset would be 0.00000000000001.

Therefore please use @jessy's answer below.



Related Topics



Leave a reply



Submit