Voici comment j'aurais précédemment tronqué un flottant à deux décimales.
NSLog(@" %.02f %.02f %.02f", r, g, b);
J'ai vérifié la documentation et le livre électronique, mais je n'ai pas réussi à le comprendre. Merci!
Ma meilleure solution jusqu'ici, suite à la réponse de David :
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
Je pense que c'est la solution la plus Swift-like, liant les opérations de formatage directement au type de données. Il se peut qu'il existe une bibliothèque intégrée d'opérations de formatage quelque part, ou peut-être sera-t-elle publiée bientôt Gardez à l'esprit que la langue est toujours en version bêta.
un moyen simple est:
print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
J'ai trouvé que String.localizedStringWithFormat
fonctionnait très bien:
Exemple:
let value: Float = 0.33333
let unit: String = "mph"
yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
C'est un moyen très rapide et simple qui n'a pas besoin de solution complexe.
let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
La plupart des réponses ici sont valables. Toutefois, si vous formatez souvent le nombre, envisagez d'étendre la classe Float pour ajouter une méthode renvoyant une chaîne mise en forme. Voir exemple de code ci-dessous. Celui-ci atteint le même objectif en utilisant un formateur de nombres et une extension.
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))")
La console affiche:
The velocity is 12.33
The velocity is 12.3
extension Float {
func string(fractionDigits:Int) -> String {
let formatter = NumberFormatter()
formatter.minimumFractionDigits = fractionDigits
formatter.maximumFractionDigits = fractionDigits
return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
}
}
Vous ne pouvez pas le faire (encore) avec une interpolation de chaîne. Votre meilleur pari sera toujours le formatage NSString:
println(NSString(format:"%.2f", sqrt(2.0)))
En extrapolant à partir de python, il semble qu'une syntaxe raisonnable pourrait être:
@infix func % (value:Double, format:String) -> String {
return NSString(format:format, value)
}
Ce qui vous permet ensuite de les utiliser comme:
M_PI % "%5.3f" // "3.142"
Vous pouvez définir des opérateurs similaires pour tous les types numériques. Malheureusement, je n'ai pas trouvé de moyen de le faire avec des génériques.
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
Pourquoi le rendre si compliqué? Vous pouvez utiliser ceci à la place:
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
Voir le travail dans la cour de récréation.
PS: Solution de: http://rrike.sh/xcode/rounding-various-decimal-places-Swift/
Une solution plus élégante et générique consiste à réécrire Ruby/python %
opérateur:
// 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]
Xcode 9.3, Swift 4.1
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
}
}
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)
Swift 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
Vous pouvez toujours utiliser NSLog dans Swift comme dans Objective-C sans le signe @.
NSLog("%.02f %.02f %.02f", r, g, b)
Edit: Après avoir travaillé avec Swift depuis un moment, je voudrais aussi ajouter cette variante
var r=1.2
var g=1.3
var b=1.4
NSLog("\(r) \(g) \(b)")
Sortie:
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)
Les réponses données jusqu'ici qui ont reçu le plus de votes s'appuient sur les méthodes NSString et vont nécessiter l'importation de Foundation.
Cela étant fait, vous avez toujours accès à NSLog.
Je pense donc que la réponse à la question, si vous demandez comment continuer à utiliser NSLog dans Swift, est simplement:
import Foundation
moins de frappe:
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)
voici une solution "pure" Swift
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)")
Pouvoir d'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)")
Sortie: La vitesse est 12.3
Aussi avec arrondi:
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
Une version de l'opérateur Ruby/python% de Vincent Guerci, mise à jour pour Swift 2.1:
func %(format:String, args:[CVarArgType]) -> String {
return String(format:format, arguments:args)
}
"Hello %@, This is pi : %.2f" % ["World", M_PI]
utiliser la méthode ci-dessous
let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)
println(output)
Vous pouvez également créer un opérateur de cette manière
operator infix <- {}
func <- (format: String, args:[CVarArg]) -> String {
return String(format: format, arguments: args)
}
let str = "%d %.1f" <- [1453, 1.123]
Beaucoup de bonnes réponses ci-dessus, mais parfois un motif est plus approprié que la sorte de "gobbledygook". Voici ma prise en utilisant un NumberFormatter dans Swift 3.
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
Ici, je voulais que 2 décimales soient toujours affichées, mais la troisième seulement si ce n’était pas zéro.
Exemple Swift2: largeur d'écran du périphérique iOS formatant le flottant en supprimant la décimale
print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
Je ne sais pas à propos de deux décimales, mais voici comment vous pouvez imprimer des flottants avec zéro décimale. J'imagine donc que vous pouvez avoir 2, 3, places ... (Remarque: vous devez convertit CGFloat en double pour passer en chaîne (format :) ou il verra une valeur de zéro)
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))
}
Qu'en est-il des extensions sur les types Double et CGFloat:
extension Double {
func formatted(_ decimalPlaces: Int?) -> String {
let theDecimalPlaces : Int
if decimalPlaces != nil {
theDecimalPlaces = decimalPlaces!
}
else {
theDecimalPlaces = 2
}
let theNumberFormatter = NumberFormatter()
theNumberFormatter.formatterBehavior = .behavior10_4
theNumberFormatter.minimumIntegerDigits = 1
theNumberFormatter.minimumFractionDigits = 1
theNumberFormatter.maximumFractionDigits = theDecimalPlaces
theNumberFormatter.usesGroupingSeparator = true
theNumberFormatter.groupingSeparator = " "
theNumberFormatter.groupingSize = 3
if let theResult = theNumberFormatter.string(from: NSNumber(value:self)) {
return theResult
}
else {
return "\(self)"
}
}
}
Usage:
let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")
impressions: 112 465 848 348 508.46
Swift 4 Mise à jour Xcode 10
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 ""
}
}
@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