精确的字符串格式说明符在Swift中

以下是我将如何截断浮点数到两位小数

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

我检查了文档和电子书,但一直没能弄清楚。 谢谢!

迄今为止,我的最好的解决方案,从大卫的回应 :

 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 

我认为这是最类似Swift的解决方案,将格式化操作直接绑定到数据类型上。 很可能是某处有内置的格式化操作库,或者很快就会发布。 请记住,该语言仍处于测试阶段。

一个简单的方法是:

 print(String(format: "hex string: %X", 123456)) print(String(format: "a float number: %.5f", 1.0321)) 

我发现String.localizedStringWithFormat工作得很好:

例:

 let value: Float = 0.33333 let unit: String = "mph" yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit) 

这是一个非常快速简单的方法,谁不需要复杂的解决方案。

 let duration = String(format: "%.01f", 3.32323242) // result = 3.3 

这里大多数答案都是有效的 但是,如果您经常格式化数字,请考虑扩展Float类以添加一个返回格式化字符串的方法。 看下面的例子代码。 这一个通过使用数字格式化和扩展来实现相同的目标。

 extension Float { func string(fractionDigits:Int) -> String { let formatter = NSNumberFormatter() formatter.minimumFractionDigits = fractionDigits formatter.maximumFractionDigits = fractionDigits return formatter.stringFromNumber(self) ?? "\(self)" } } let myVelocity:Float = 12.32982342034 println("The velocity is \(myVelocity.string(2))") println("The velocity is \(myVelocity.string(1))") 

控制台显示:

 The velocity is 12.33 The velocity is 12.3 

SWIFT 3.1更新

 extension Float { func string(fractionDigits:Int) -> String { let formatter = NumberFormatter() formatter.minimumFractionDigits = fractionDigits formatter.maximumFractionDigits = fractionDigits return formatter.string(from: NSNumber(value: self)) ?? "\(self)" } } 

你不能用字符串插值(还)。 你最好的选择仍然是NSString格式:

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

从python推断,似乎是一个合理的语法可能是:

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

然后允许你使用它们:

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

你可以为所有的数字类型定义类似的运算符,不幸的是,我还没有找到一种方法来处理泛型。

 import Foundation extension CGFloat { var string1: String { return String(format: "%.1f", self) } var string2: String { return String(format: "%.2f", self) } } 

用法

 let offset = CGPoint(1.23, 4.56) print("offset: \(offset.x.string1) x \(offset.y.string1)") // offset: 1.2 x 4.6 

更优雅和通用的解决方案是重写ruby / python %操作符:

 // Updated for beta 5 func %(format:String, args:[CVarArgType]) -> String { return NSString(format:format, arguments:getVaList(args)) } "Hello %@, This is pi : %.2f" % ["World", M_PI] 

为什么这么复杂? 你可以用它来代替:

 import UIKit let PI = 3.14159265359 round( PI ) // 3.0 rounded to the nearest decimal round( PI * 100 ) / 100 //3.14 rounded to the nearest hundredth round( PI * 1000 ) / 1000 // 3.142 rounded to the nearest thousandth 

看它在游乐场工作。

PS:解决方案来自: http : //rrike.sh/xcode/rounding-various-decimal-places-swift/

在Objective-C中,你仍然可以在Swift中使用NSLog,而不需要@符号。

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

编辑:自从一段时间以来,我也想加入这个变化

  var r=1.2 var g=1.3 var b=1.4 NSLog("\(r) \(g) \(b)") 

输出:

 2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4 
 extension Double { func formatWithDecimalPlaces(decimalPlaces: Int) -> Double { let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String return Double(formattedString)! } } 1.3333.formatWithDecimalPlaces(2) 

这里是一个“纯粹”的快速解决方案

  var d = 1.234567 operator infix ~> {} @infix func ~> (left: Double, right: Int) -> String { if right == 0 { return "\(Int(left))" } var k = 1.0 for i in 1..right+1 { k = 10.0 * k } let n = Double(Int(left*k)) / Double(k) return "\(n)" } println("\(d~>2)") println("\(d~>1)") println("\(d~>0)") 

迄今为止获得最多选票的答案依赖于NSString方法,并要求您已经导入Foundation。

但是,完成之后,您仍然可以访问NSLog。

所以我想这个问题的答案是,如果你问如何继续在Swift中使用NSLog,简单地说:

import Foundation

扩展的力量

 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)") 

输出:速度是12.3

少打字的方式:

 func fprint(format: String, _ args: CVarArgType...) { print(NSString(format: format, arguments: getVaList(args))) } 
 //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) 

还有四舍五入:

 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 

使用下面的方法

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

文森特Guerci的红宝石/ python%运算符版本,更新为Swift 2.1:

 func %(format:String, args:[CVarArgType]) -> String { return String(format:format, arguments:args) } "Hello %@, This is pi : %.2f" % ["World", M_PI] 

细节

xCode 9.0.1,Swift 4.0

 import Foundation extension CustomStringConvertible { private func _precision(number: NSNumber, precision: Int, roundingMode: NumberFormatter.RoundingMode) -> String? { let formatter = NumberFormatter() formatter.minimumFractionDigits = precision formatter.roundingMode = roundingMode return formatter.string(from: number) } func precision(_ number: Int, roundingMode: NumberFormatter.RoundingMode = NumberFormatter.RoundingMode.halfUp) -> String? { 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 } } 

用法

 import UIKit let double: Double = 2312.1987654321 let float = Float(double) let cgfloat = CGFloat(double) print("DOUBLE (\(double))\n" + ("\(double)".precision(3) ?? "nil")) print(double.precision(3) ?? "nil") print(double.precision(3, roundingMode: .down) ?? "nil") print("\nFLOAT (\(float))\n" + ("\(float)".precision(3) ?? "nil")) print(float.precision(3) ?? "nil") print(float.precision(3, roundingMode: .down) ?? "nil") print("\nCGFLOAT (\(cgfloat))\n" + ("\(cgfloat)".precision(3) ?? "nil")) print(cgfloat.precision(3) ?? "nil") print(cgfloat.precision(3, roundingMode: .down) ?? "nil") 

结果

在这里输入图像描述

 @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 

你也可以用这种方式创建一个操作符

 operator infix <- {} func <- (format: String, args:[CVarArg]) -> String { return String(format: format, arguments: args) } let str = "%d %.1f" <- [1453, 1.123] 

我不知道有两位小数,但这里是如何打印带有小数点后0位的浮点数,所以我想可以是2个地方,3个地方…(注意:您必须将CGFloat转换为Double来传递以字符串(格式:)或它将看到一个值为零)

 func logRect(r: CGRect, _ title: String = "") { println(String(format: "[ (%.0f, %.0f), (%.0f, %.0f) ] %@", Double(r.origin.x), Double(r.origin.y), Double(r.size.width), Double(r.size.height), title)) } 

Swift2例子:iOS设备的屏幕宽度,格式化Float去除小数

 print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame))) 

上面有很多很好的答案,但是有时候一个模式比“%.3f”这样的gobbledygook更合适。 下面是我在Swift 3中使用NumberFormatter的一个示例。

 extension Double { func format(_ pattern: String) -> String { let formatter = NumberFormatter() formatter.format = pattern return formatter.string(from: NSNumber(value: self))! } } let n1 = 0.350, n2 = 0.355 print(n1.format("0.00#")) // 0.35 print(n2.format("0.00#")) // 0.355 

在这里,我想要总是显示2位小数,但只有在不为零时才显示第三位。

@Christian Dietrich:

代替:

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

它也可以是:

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

[纠错:]对不起,混淆* – 当然这与双打。 我认为,最实际的(如果你想数字四舍五入,不切断),这将是这样的:

 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 } 

对于Float而言,只需将Double替换为Float,powf替换powe并将其替换为roundf。
更新:我发现使用返回类型Double而不是String是最实际的。 对于字符串输出它的工作原理是一样的,即:

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

版画:Pi大约是3.142
所以你可以用同样的方式来处理字符串(你甚至可以写:println(d〜> 2)),另外你也可以直接使用它来循环取值,例如:

 d = Double(slider.value) ~> 2 

或任何你需要…