53

What is the function that removes trailing zeros from doubles?

var double = 3.0
var double2 = 3.10

println(func(double)) // 3
println(func(double2)) // 3.1
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
Bogdan Bogdanov
  • 882
  • 11
  • 36
  • 79
  • 7
    A *double* does not have trailing zeros, only its *string representation*. Have a look at `NSNumberFormatter` or `String(format: ...)`. There should already be some examples for both here on SO. – Martin R Apr 10 '15 at 11:57
  • You could also use numberFormatter as in this example: https://stackoverflow.com/questions/30663996/format-string-with-trailing-zeros-removed-for-x-decimal-places-in-swift/30664610 – wolffan Jan 11 '18 at 16:49
  • Possible duplicate of [Swift - How to remove a decimal from a float if the decimal is equal to 0?](https://stackoverflow.com/questions/31390466/swift-how-to-remove-a-decimal-from-a-float-if-the-decimal-is-equal-to-0) – Cœur Sep 13 '18 at 08:55

6 Answers6

83

You can do it this way but it will return a string:

var double = 3.0
var double2 = 3.10

func forTrailingZero(_ temp: Double) -> String {
    var tempVar = String(format: "%g", temp)
    return tempVar
}

forTrailingZero(double)   //3
forTrailingZero(double2)  //3.1
Joannes
  • 2,569
  • 3
  • 17
  • 39
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
  • 15
    Note that the "%g" format switches to the scientific notation if the number becomes too large: `forTailingZero(123456789) == 1.23457e+08` :) – Martin R Apr 10 '15 at 12:08
  • 11
    I think the more optimal solution is described in this answer: http://stackoverflow.com/a/30664610/2859764 – Akshit Zaveri Feb 26 '17 at 13:42
63

In Swift 4 you can do it like that:

extension Double {
    func removeZerosFromEnd() -> String {
        let formatter = NumberFormatter()
        let number = NSNumber(value: self)
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 16 //maximum digits in Double after dot (maximum precision)
        return String(formatter.string(from: number) ?? "")
    }
}

example of use: print (Double("128834.567891000").removeZerosFromEnd()) result: 128834.567891

You can also count how many decimal digits has your string:

import Foundation

extension Double {
    func removeZerosFromEnd() -> String {
        let formatter = NumberFormatter()
        let number = NSNumber(value: self)
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = (self.components(separatedBy: ".").last)!.count
        return String(formatter.string(from: number) ?? "")
    }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Grzegorz R. Kulesza
  • 1,324
  • 16
  • 10
26

Removing trailing zeros in output

This scenario is good when the default output precision is desired. We test the value for potential trailing zeros, and we use a different output format depending on it.

extension Double {
    var stringWithoutZeroFraction: String {
        return truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

(works also with extension Float, but not Float80)

Output:

1.0 → "1"
0.1 → "0.1"
0.01 → "0.01"
0.001 → "0.001"
0.0001 → "0.0001"

Formatting with maximum fraction digits, without trailing zeros

This scenario is good when a custom output precision is desired. This solution seems roughly as fast as NumberFormatter + NSNumber solution from MirekE, but one benefit could be that we're avoiding NSObject here.

extension Double {
    func string(maximumFractionDigits: Int = 2) -> String {
        let s = String(format: "%.\(maximumFractionDigits)f", self)
        for i in stride(from: 0, to: -maximumFractionDigits, by: -1) {
            if s[s.index(s.endIndex, offsetBy: i - 1)] != "0" {
                return String(s[..<s.index(s.endIndex, offsetBy: i)])
            }
        }
        return String(s[..<s.index(s.endIndex, offsetBy: -maximumFractionDigits - 1)])
    }
}

(works also with extension Float, but not Float80)

Output for maximumFractionDigits: 2:

1.0 → "1"
0.12 → "0.12"
0.012 → "0.01"
0.0012 → "0"
0.00012 → "0"

Note that it performs a rounding (same as MirekE solution):

0.9950000 → "0.99"
0.9950001 → "1"

Community
  • 1
  • 1
Cœur
  • 37,241
  • 25
  • 195
  • 267
4

In case you're looking how to remove trailing zeros from a string:

string.replacingOccurrences(of: "^([\d,]+)$|^([\d,]+)\.0*$|^([\d,]+\.[0-9]*?)0*$", with: "$1$2$3", options: .regularExpression)

This will transform strings like "0.123000000" into "0.123"

Ilya Shevyryaev
  • 756
  • 6
  • 8
3

All the answers i found was good but all of them had some problems like producing decimal numbers without the 0 in the beginning ( like .123 instead of 0.123). but these two will do the job with no problem :

extension Double {
    func formatNumberWithFixedFraction(maximumFraction: Int = 8) -> String {
        let stringFloatNumber = String(format: "%.\(maximumFraction)f", self)
        return stringFloatNumber
    }
    
    func formatNumber(maximumFraction: Int = 8) -> String {
        let formatter = NumberFormatter()
        let number = NSNumber(value: self)
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = maximumFraction
        formatter.numberStyle = .decimal
        formatter.allowsFloats = true
        let formattedNumber = formatter.string(from: number).unwrap
        return formattedNumber
    }
}

The first one converts 71238.12 with maxFraction of 8 to: 71238.12000000 but the second one with maxFraction of 8 converts it to: 71238.12

Mehrdad
  • 1,050
  • 1
  • 16
  • 27
1

This one works for me, returning it as a String for a text label

func ridZero(result: Double) -> String {
        let value = String(format: "%g", result)
        return value
}

Following results

ridZero(result: 3.0) // "3"
ridZero(result: 3.5) // "3.5"
N4SK
  • 700
  • 8
  • 25
Patricia O
  • 11
  • 1