Voici comment j'aurais précédemment tronqué un flotteur à deux décimales
NSLog(@" %.02f %.02f %.02f", r, g, b);
J'ai vérifié les documents et le livre électronique, mais je n'ai pas pu le comprendre. Merci!
Voici comment j'aurais précédemment tronqué un flotteur à deux décimales
NSLog(@" %.02f %.02f %.02f", r, g, b);
J'ai vérifié les documents et le livre électronique, mais je n'ai pas pu le comprendre. Merci!
Réponses:
Ma meilleure solution jusqu'à présent, 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 proche de Swift, liant les opérations de formatage directement au type de données. Il se pourrait bien qu'il y ait une bibliothèque intégrée d'opérations de formatage quelque part, ou peut-être qu'elle sera bientôt publiée. Gardez à l'esprit que la langue est toujours en version bêta.
un moyen simple est:
import Foundation // required for String(format: _, _)
print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
println(String(format: "a float number: %.5f", 1.0321))
printf
sans avoir à écrire des extensions distinctes.
import Foundation
J'ai trouvé que ça String.localizedStringWithFormat
fonctionnait assez 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
Col 16: 'init' has been renamed to 'init(describing:)'
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 qui renvoie une chaîne formatée. Voir l'exemple de code ci-dessous. Celui-ci atteint le même objectif en utilisant un formateur et une extension de nombre.
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)"
}
}
NSNumberFormatter
, comme cette réponse. Les autres réponses très votées ne reflètent tout simplement pas les paramètres régionaux du périphérique (par exemple, dans certains pays, ils utilisent une virgule pour une décimale; cela reflète cela; d'autres réponses ne le font pas).
NSNumberFormatter
est assez lente à initialiser. Si possible, cela aide à en définir un et à le réutiliser. Cela dit, je lis ici cette question parce que ce n'est pas possible dans mon cas.
Vous ne pouvez pas (encore) le faire 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 puisse ê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.
Mise à jour Swift 5
À partir d'au moins Swift 5, String
prend directement en charge l' format:
initialiseur, il n'est donc pas nécessaire d'utiliser NSString
et l' @infix
attribut n'est plus nécessaire, ce qui signifie que les exemples ci-dessus doivent être écrits comme suit:
println(String(format:"%.2f", sqrt(2.0)))
func %(value:Double, format:String) -> String {
return String(format:format, value)
}
Double.pi % "%5.3f" // "3.142"
[NSString stringWithFormat...
Pourquoi rendre cela 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
Voyez-le fonctionner dans Playground.
PS: Solution de: http://rrike.sh/xcode/rounding-various-decimal-places-swift/
Une solution plus élégante et générique consiste à réécrire l' %
opérateur 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]
"Hello %@, This is pi : %.2f" % ["World", M_PI]
ça marche, mais étrangement "%@ %@" % ["Hello", "World"]
augmenter can't unsafeBitCast
... Je suppose que cela sera corrigé dans la prochaine version.
,
n'est pas un opérateur de caractères valide, dans Swift et dans la plupart des langues. Et imo, il est préférable d'utiliser un %
opérateur qui existe déjà dans d'autres langues. Voir developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Swift 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
Vous pouvez toujours utiliser NSLog dans Swift comme dans Objective-C juste sans le signe @.
NSLog("%.02f %.02f %.02f", r, g, b)
Edit: Après avoir travaillé avec Swift depuis un moment, je voudrais ajouter également cette variation
var r=1.2
var g=1.3
var b=1.4
NSLog("\(r) \(g) \(b)")
Production:
2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4
(5.2).rounded()
// 5.0
(5.5).rounded()
// 6.0
(-5.2).rounded()
// -5.0
(-5.5).rounded()
// -6.0
func arrondi (règle _: FloatingPointRoundingRule) -> Double
let x = 6.5
// Equivalent to the C 'round' function:
print(x.rounded(.toNearestOrAwayFromZero))
// Prints "7.0"
// Equivalent to the C 'trunc' function:
print(x.rounded(.towardZero))
// Prints "6.0"
// Equivalent to the C 'ceil' function:
print(x.rounded(.up))
// Prints "7.0"
// Equivalent to the C 'floor' function:
print(x.rounded(.down))
// Prints "6.0"
var x = 5.2
x.round()
// x == 5.0
var y = 5.5
y.round()
// y == 6.0
var z = -5.5
z.round()
// z == -6.0
mutation func round (règle _: FloatingPointRoundingRule)
// Equivalent to the C 'round' function:
var w = 6.5
w.round(.toNearestOrAwayFromZero)
// w == 7.0
// Equivalent to the C 'trunc' function:
var x = 6.5
x.round(.towardZero)
// x == 6.0
// Equivalent to the C 'ceil' function:
var y = 6.5
y.round(.up)
// y == 7.0
// Equivalent to the C 'floor' function:
var z = 6.5
z.round(.down)
// z == 6.0
extension Numeric {
private func _precision(number: NSNumber, formatter: NumberFormatter) -> Self? {
if let formatedNumString = formatter.string(from: number),
let formatedNum = formatter.number(from: formatedNumString) {
return formatedNum as? Self
}
return nil
}
private func toNSNumber() -> NSNumber? {
if let num = self as? NSNumber { return num }
guard let string = self as? String, let double = Double(string) else { return nil }
return NSNumber(value: double)
}
func precision(_ minimumFractionDigits: Int,
roundingMode: NumberFormatter.RoundingMode = NumberFormatter.RoundingMode.halfUp) -> Self? {
guard let number = toNSNumber() else { return nil }
let formatter = NumberFormatter()
formatter.minimumFractionDigits = minimumFractionDigits
formatter.roundingMode = roundingMode
return _precision(number: number, formatter: formatter)
}
func precision(with numberFormatter: NumberFormatter) -> String? {
guard let number = toNSNumber() else { return nil }
return numberFormatter.string(from: number)
}
}
_ = 123.44.precision(2)
_ = 123.44.precision(3, roundingMode: .up)
let numberFormatter = NumberFormatter()
numberFormatter.minimumFractionDigits = 1
numberFormatter.groupingSeparator = " "
let num = 222.3333
_ = num.precision(2)
func option1<T: Numeric>(value: T, numerFormatter: NumberFormatter? = nil) {
print("Type: \(type(of: value))")
print("Original Value: \(value)")
let value1 = value.precision(2)
print("value1 = \(value1 != nil ? "\(value1!)" : "nil")")
let value2 = value.precision(5)
print("value2 = \(value2 != nil ? "\(value2!)" : "nil")")
if let value1 = value1, let value2 = value2 {
print("value1 + value2 = \(value1 + value2)")
}
print("")
}
func option2<T: Numeric>(value: T, numberFormatter: NumberFormatter) {
print("Type: \(type(of: value))")
print("Original Value: \(value)")
let value1 = value.precision(with: numberFormatter)
print("formated value = \(value1 != nil ? "\(value1!)" : "nil")\n")
}
func test(with double: Double) {
print("===========================\nTest with: \(double)\n")
let float = Float(double)
let float32 = Float32(double)
let float64 = Float64(double)
let float80 = Float80(double)
let cgfloat = CGFloat(double)
// Exapmle 1
print("-- Option1\n")
option1(value: double)
option1(value: float)
option1(value: float32)
option1(value: float64)
option1(value: float80)
option1(value: cgfloat)
// Exapmle 2
let numberFormatter = NumberFormatter()
numberFormatter.formatterBehavior = .behavior10_4
numberFormatter.minimumIntegerDigits = 1
numberFormatter.minimumFractionDigits = 4
numberFormatter.maximumFractionDigits = 9
numberFormatter.usesGroupingSeparator = true
numberFormatter.groupingSeparator = " "
numberFormatter.groupingSize = 3
print("-- Option 2\n")
option2(value: double, numberFormatter: numberFormatter)
option2(value: float, numberFormatter: numberFormatter)
option2(value: float32, numberFormatter: numberFormatter)
option2(value: float64, numberFormatter: numberFormatter)
option2(value: float80, numberFormatter: numberFormatter)
option2(value: cgfloat, numberFormatter: numberFormatter)
}
test(with: 123.22)
test(with: 1234567890987654321.0987654321)
===========================
Test with: 123.22
-- Option1
Type: Double
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
Type: Float
Original Value: 123.22
value1 = nil
value2 = nil
Type: Float
Original Value: 123.22
value1 = nil
value2 = nil
Type: Double
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
Type: Float80
Original Value: 123.21999999999999886
value1 = nil
value2 = nil
Type: CGFloat
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
-- Option 2
Type: Double
Original Value: 123.22
formatted value = 123.2200
Type: Float
Original Value: 123.22
formatted value = 123.220001221
Type: Float
Original Value: 123.22
formatted value = 123.220001221
Type: Double
Original Value: 123.22
formatted value = 123.2200
Type: Float80
Original Value: 123.21999999999999886
formatted value = nil
Type: CGFloat
Original Value: 123.22
formatted value = 123.2200
===========================
Test with: 1.2345678909876544e+18
-- Option1
Type: Double
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
Type: Float
Original Value: 1.234568e+18
value1 = nil
value2 = nil
Type: Float
Original Value: 1.234568e+18
value1 = nil
value2 = nil
Type: Double
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
Type: Float80
Original Value: 1234567890987654400.0
value1 = nil
value2 = nil
Type: CGFloat
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
-- Option 2
Type: Double
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
Type: Float
Original Value: 1.234568e+18
formatted value = 1 234 567 939 550 610 000.0000
Type: Float
Original Value: 1.234568e+18
formatted value = 1 234 567 939 550 610 000.0000
Type: Double
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
Type: Float80
Original Value: 1234567890987654400.0
formatted value = nil
Type: CGFloat
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
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 reposent sur les méthodes NSString et vont exiger que vous ayez importé Foundation.
Cela dit, 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
//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)
ici une solution rapide "pure"
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 de 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
utiliser la méthode ci-dessous
let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)
println(output)
Beaucoup de bonnes réponses ci-dessus, mais parfois un modèle est plus approprié que le genre de charabia "% .3f". Voici mon point de vue 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 elle n'était pas nulle.
Mise à jour de Swift 4 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 ""
}
}
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))")
tirages: 112 465 848 348 508,46
@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
Je ne connais pas deux décimales, mais voici comment imprimer des flottants avec zéro décimale, alors j'imagine que ça peut être 2, 3, ... (Remarque: vous devez convertir CGFloat en Double pour passer à String (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))
}
Exemple Swift2: largeur d'écran d'un appareil iOS formatant le flottant en supprimant la décimale
print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
@Christian Dietrich:
au lieu de:
var k = 1.0
for i in 1...right+1 {
k = 10.0 * k
}
let n = Double(Int(left*k)) / Double(k)
return "\(n)"
cela pourrait aussi être:
let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"
[correction:] Désolé pour la confusion * - Bien sûr, cela fonctionne avec les doubles. Je pense que, plus pratique (si vous voulez que les chiffres soient arrondis, pas coupés), ce serait quelque chose comme ça:
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
}
Pour Float uniquement, remplacez simplement Double par Float, pow avec powf et round avec roundf.
Mise à jour: j'ai trouvé qu'il est plus pratique d'utiliser le type de retour Double au lieu de String. Il en va de même pour la sortie String, c'est-à-dire:
println("Pi is roughly \(3.1415926 ~> 3)")
imprime: Pi est à peu près 3,142.
Vous pouvez donc l'utiliser de la même manière pour les chaînes (vous pouvez même toujours écrire: println (d ~> 2)), mais en plus, vous pouvez également l'utiliser pour arrondir directement les valeurs, à savoir:
d = Double(slider.value) ~> 2
ou tout ce dont vous avez besoin…