Precision String Format Specifier In Swift

2018-12-31 08:29发布

Below is how I would have previously truncated a float to two decimal places

NSLog(@" %.02f %.02f %.02f", r, g, b);

I checked the docs and the eBook but haven't been able to figure it out. Thanks!

标签: swift
29条回答
爱死公子算了
2楼-- · 2018-12-31 08:51

Details

Xcode 9.3, Swift 4.1

Solution

import Foundation

extension Numeric {

    private func _precision(number: NSNumber, precision: Int, roundingMode: NumberFormatter.RoundingMode) -> Self? {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = precision
        formatter.roundingMode = roundingMode
        if let formatedNumString = formatter.string(from: number), let formatedNum = formatter.number(from: formatedNumString) {
            return formatedNum as? Self
        }
        return nil

    }

    func precision(_ number: Int, roundingMode: NumberFormatter.RoundingMode = NumberFormatter.RoundingMode.halfUp) -> Self? {

        if let num = self as? NSNumber {
            return _precision(number: num, precision: number, roundingMode: roundingMode)
        }
        if let string = self as? String, let double = Double(string) {
            return _precision(number: NSNumber(value: double), precision: number, roundingMode: roundingMode)
        }
        return nil
    }

}

Usage

import UIKit

func showInfo<T: Numeric>(value: T) {
    print("Type: \(type(of: value))")
    print("Original Value: \(value)")
    let value1 = value.precision(3)
    print("value1 = \(value1 != nil ? "\(value1!)" : "nil")")
    let value2 = value.precision(2)
    print("value2 = \(value2 != nil ? "\(value2!)" : "nil")")
    if let value1 = value1, let value2 = value2 {
        print("value1 + value2 = \(value1 + value2)")
    }
    print("")
}

let double: Double = 232.1987654321
let float = Float(double)
let cgfloat = CGFloat(double)

showInfo(value: double)
showInfo(value: float)
showInfo(value: cgfloat)

Result

enter image description here

查看更多
裙下三千臣
3楼-- · 2018-12-31 08:53

My best solution so far, following from David's response:

import Foundation

extension Int {
    func format(f: String) -> String {
        return String(format: "%\(f)d", self)
    }
}

extension Double {
    func format(f: String) -> String {
        return String(format: "%\(f)f", self)
    }
}

let someInt = 4, someIntFormat = "03"
println("The integer number \(someInt) formatted with \"\(someIntFormat)\" looks like \(someInt.format(someIntFormat))")
// The integer number 4 formatted with "03" looks like 004

let someDouble = 3.14159265359, someDoubleFormat = ".3"
println("The floating point number \(someDouble) formatted with \"\(someDoubleFormat)\" looks like \(someDouble.format(someDoubleFormat))")
// The floating point number 3.14159265359 formatted with ".3" looks like 3.142

I think this is the most Swift-like solution, tying the formatting operations directly to the data type. It may well be that there is a built-in library of formatting operations somewhere, or maybe it will be released soon. Keep in mind that the language is still in beta.

查看更多
长期被迫恋爱
4楼-- · 2018-12-31 08:53

Power of extension

extension Double {
    var asNumber:String {
        if self >= 0 {
            var formatter = NSNumberFormatter()
            formatter.numberStyle = .NoStyle
            formatter.percentSymbol = ""
            formatter.maximumFractionDigits = 1
            return "\(formatter.stringFromNumber(self)!)"
        }
        return ""
    }
}

let velocity:Float = 12.32982342034

println("The velocity is \(velocity.toNumber)")

Output: The velocity is 12.3

查看更多
余生无你
5楼-- · 2018-12-31 08:54
//It will more help, by specify how much decimal Point you want.
let decimalPoint = 2
let floatAmount = 1.10001
let amountValue = String(format: "%0.*f", decimalPoint, floatAmount)
查看更多
伤终究还是伤i
6楼-- · 2018-12-31 08:54

use

CGFloat 

or

Float.roundTo(places:2)
查看更多
泪湿衣
7楼-- · 2018-12-31 08:55

a simple way is:

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
查看更多
登录 后发表回答