Formatting decimal places with unknown number

后端 未结 4 1440
青春惊慌失措
青春惊慌失措 2020-12-04 02:29

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 th

相关标签:
4条回答
  • 2020-12-04 02:46

    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
    
    0 讨论(0)
  • 2020-12-04 02:56

    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
    
    0 讨论(0)
  • 2020-12-04 02:57

    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"
    
    0 讨论(0)
  • 2020-12-04 03:03

    If you want to print a floating point number to 3 decimal places, you can use String(format: "%.3f"). This will round, so 0.10000001 becomes 0.100, 0.1009 becomes 0.101 etc.

    But it sounds like you don’t want the trailing zeros, so you might want to trim them off. (is there a way to do this with format? edit: yes, g as @simons points out)

    Finally, this really shouldn’t be a class function since it’s operating on primitive types. Better to either make it a free function, or perhaps extend Double/Float:

    extension Double {
        func toString(#decimalPlaces: Int)->String {
            return String(format: "%.\(decimalPlaces)g", self)
        }
    }
    
    let number = -0.3009
    number.toString(decimalPlaces: 3)  // -0.301
    
    0 讨论(0)
提交回复
热议问题