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 09:03

Swift 4 Xcode 10 Update

extension Double {
    var asNumber:String {
        if self >= 0 {
            let formatter = NumberFormatter()
            formatter.numberStyle = .none
            formatter.percentSymbol = ""
            formatter.maximumFractionDigits = 2
            return "\(formatter.string(from: NSNumber(value: self)) ?? "")"
        }
        return ""
    }
}
查看更多
无色无味的生活
3楼-- · 2018-12-31 09:05

You can't do it (yet) with string interpolation. Your best bet is still going to be NSString formatting:

println(NSString(format:"%.2f", sqrt(2.0)))

Extrapolating from python, it seems like a reasonable syntax might be:

@infix func % (value:Double, format:String) -> String {
    return NSString(format:format, value)
}

Which then allows you to use them as:

M_PI % "%5.3f"                // "3.142"

You can define similar operators for all of the numeric types, unfortunately I haven't found a way to do it with generics.

查看更多
流年柔荑漫光年
4楼-- · 2018-12-31 09:06

Also with rounding:

extension Float
{
    func format(f: String) -> String
    {
        return NSString(format: "%\(f)f", self)
    }
    mutating func roundTo(f: String)
    {
        self = NSString(format: "%\(f)f", self).floatValue
    }
}

extension Double
{
    func format(f: String) -> String
    {
        return NSString(format: "%\(f)f", self)
    }
    mutating func roundTo(f: String)
    {
        self = NSString(format: "%\(f)f", self).doubleValue
    }
}

x = 0.90695652173913
x.roundTo(".2")
println(x) //0.91
查看更多
高级女魔头
5楼-- · 2018-12-31 09:06
@infix func ^(left:Double, right: Int) -> NSNumber {
    let nf = NSNumberFormatter()
    nf.maximumSignificantDigits = Int(right)
    return  nf.numberFromString(nf.stringFromNumber(left))
}


let r = 0.52264
let g = 0.22643
let b = 0.94837

println("this is a color: \(r^3) \(g^3) \(b^3)")

// this is a color: 0.523 0.226 0.948
查看更多
裙下三千臣
6楼-- · 2018-12-31 09:06

@Christian Dietrich:

instead of:

var k = 1.0
    for i in 1...right+1 {
        k = 10.0 * k
    }
let n = Double(Int(left*k)) / Double(k)
return "\(n)"

it could also be:

let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"

[correction:] Sorry for confusion* - Of course this works with Doubles. I think, most practical (if you want digits to be rounded, not cut off) it would be something like that:

infix operator ~> {}
func ~> (left: Double, right: Int) -> Double {
    if right <= 0 {
        return round(left)
    }
    let k = pow(10.0, Double(right))
    return round(left*k) / k
}

For Float only, simply replace Double with Float, pow with powf and round with roundf.
Update: I found that it is most practical to use return type Double instead of String. It works the same for String output, i.e.:

println("Pi is roughly \(3.1415926 ~> 3)")

prints: Pi is roughly 3.142
So you can use it the same way for Strings (you can even still write: println(d ~> 2)), but additionally you can also use it to round values directly, i.e.:

d = Double(slider.value) ~> 2

or whatever you need …

查看更多
永恒的永恒
7楼-- · 2018-12-31 09:07

use below method

let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)

println(output)
查看更多
登录 后发表回答