Specifier per il formato stringa di precisione in Swift

Di seguito è riportato come avrei precedentemente troncato un float con due cifre decimali

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

Ho controllato i documenti e l’eBook ma non sono stato in grado di capirlo. Grazie!

La mia migliore soluzione finora, in seguito alla risposta di 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 

Penso che questa sia la soluzione più veloce, legando le operazioni di formattazione direttamente al tipo di dati. Potrebbe essere che ci sia una libreria incorporata di operazioni di formattazione da qualche parte, o forse verrà rilasciata presto. Tieni presente che la lingua è ancora in beta.

un modo semplice è:

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

Ho trovato String.localizedStringWithFormat per funzionare abbastanza bene:

Esempio:

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

Questo è un modo molto veloce e semplice che non ha bisogno di soluzioni complesse.

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

La maggior parte delle risposte qui sono valide. Tuttavia, nel caso in cui si formi spesso il numero, prendere in considerazione l’estensione della class Float per aggiungere un metodo che restituisce una stringa formattata. Vedi il codice di esempio qui sotto. Questo raggiunge lo stesso objective utilizzando un formattatore ed estensione numerici.

 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 mostra:

 The velocity is 12.33 The velocity is 12.3 

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

Non è ansible farlo (ancora) con l’interpolazione delle stringhe. La tua migliore scommessa sarà comunque la formattazione NSString:

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

Estrapolando da python, sembra che una syntax ragionevole potrebbe essere:

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

Che poi ti permette di usarli come:

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

È ansible definire operatori simili per tutti i tipi numerici, sfortunatamente non ho trovato un modo per farlo con i generici.

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

uso

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

Perché renderlo così complicato? Puoi usare questo invece:

 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 

Vedi funziona in Playground.

PS: Soluzione da: http://rrike.sh/xcode/rounding-various-decimal-places-swift/

Una soluzione più elegante e generica è quella di riscrivere l’operatore di 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] 

Puoi ancora usare NSLog in Swift come in Objective-C senza il simbolo @.

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

Modifica: dopo aver lavorato con Swift da un po ‘vorrei aggiungere anche questa variazione

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

Produzione:

 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) 

Dettagli

Xcode 9.2.1, Swift 4

Soluzione

 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 } } 

uso

 import UIKit func showInfo(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) 

Risultato

inserisci la descrizione dell'immagine qui

Le risposte date finora che hanno ricevuto il maggior numero di voti si basano sui metodi NSString e richiedono che tu abbia importato Foundation.

Fatto ciò, hai comunque accesso a NSLog.

Quindi penso che la risposta alla domanda, se stai chiedendo come continuare ad usare NSLog in Swift, è semplicemente:

import Foundation

ecco una soluzione “pura” rapida

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

Potere di estensione

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

Uscita: la velocità è 12,3

meno modo di battitura:

 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) 

Swift 4

 let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123) 

Puoi anche creare un operatore in questo modo

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

Anche con arrotondamento:

 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 

utilizzare sotto il metodo

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

Una versione dell’operatore ruby ​​/ python% di Vincent Guerci, aggiornato per Swift 2.1:

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

Un sacco di buone risposte sopra, ma a volte un modello è più appropriato della “% .3f” sorta di gobbledygook. Ecco il mio modo di utilizzare un NumberFormatter in 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 

Qui volevo mostrare 2 decimali, ma il terzo solo se non era zero.

 @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 

Non so circa due cifre decimali, ma ecco come puoi stampare float con zero decimali, quindi immagino che possa essere 2, 3, posti … (Nota: devi convertire CGFloat in Double per passare alla stringa (formato 🙂 o vedrà un valore pari a zero)

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

Esempio di Swift2: Larghezza dello schermo del dispositivo iOS con formattazione di Float che rimuove il decimale

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

uso

 CGFloat 

o

 Float.roundTo(places:2) 

@Christian Dietrich:

invece di:

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

potrebbe anche essere:

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

[correzione:] Scusa per la confusione * – Ovviamente questo funziona con il doppio. Penso che la cosa più pratica (se vuoi che le cifre siano arrotondate, non tagliate) sarebbe qualcosa del genere:

 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 } 

Solo per Float, basta sostituire Double con Float, pow con powf e round con roundf.
Aggiornamento: ho scoperto che è più pratico utilizzare il tipo di ritorno Double anziché String. Funziona allo stesso modo per l'output di String, ovvero:

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

stampe: Pi è circa 3.142
Quindi puoi usarlo allo stesso modo per le stringhe (puoi persino scrivere ancora: println (d ~> 2)), ma in aggiunta puoi anche usarlo per arrotondare i valori direttamente, cioè:

 d = Double(slider.value) ~> 2 

o qualunque cosa tu abbia bisogno ...