Im Folgenden wird beschrieben, wie ich zuvor einen Gleitkommawert auf zwei Dezimalstellen abgeschnitten hätte
NSLog(@" %.02f %.02f %.02f", r, g, b);
Ich habe die Dokumente und das eBook überprüft, konnte es aber nicht herausfinden. Vielen Dank!
Im Folgenden wird beschrieben, wie ich zuvor einen Gleitkommawert auf zwei Dezimalstellen abgeschnitten hätte
NSLog(@" %.02f %.02f %.02f", r, g, b);
Ich habe die Dokumente und das eBook überprüft, konnte es aber nicht herausfinden. Vielen Dank!
Antworten:
Meine bisher beste Lösung nach Davids Antwort :
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
Ich denke, dies ist die schnellste Lösung, bei der die Formatierungsvorgänge direkt mit dem Datentyp verknüpft werden. Es kann durchaus sein, dass irgendwo eine Bibliothek mit Formatierungsvorgängen integriert ist, oder sie wird bald veröffentlicht. Beachten Sie, dass sich die Sprache noch in der Beta befindet.
Ein einfacher Weg ist:
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
ohne dass separate Erweiterungen geschrieben werden müssen.
import Foundation
Ich fand String.localizedStringWithFormat
es ziemlich gut zu arbeiten:
Beispiel:
let value: Float = 0.33333
let unit: String = "mph"
yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Dies ist ein sehr schneller und einfacher Weg, der keine komplexe Lösung benötigt.
let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
Col 16: 'init' has been renamed to 'init(describing:)'
Die meisten Antworten hier sind gültig. Wenn Sie die Zahl jedoch häufig formatieren, sollten Sie die Float-Klasse erweitern, um eine Methode hinzuzufügen, die eine formatierte Zeichenfolge zurückgibt. Siehe Beispielcode unten. Dieser erreicht das gleiche Ziel, indem er einen Zahlenformatierer und eine Erweiterung verwendet.
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))")
Die Konsole zeigt:
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
diese Antwort verwenden. Die anderen Antworten mit hoher Abstimmung spiegeln einfach nicht die Einstellungen des Gerätegebietsschemas wider (z. B. verwenden sie in einigen Gebietsschemas ein Komma als Dezimalstelle; dies spiegelt dies wider; andere Antworten tun dies nicht).
NSNumberFormatter
nur langsam initialisieren lässt. Wenn möglich, ist es hilfreich, eine zu definieren und wiederzuverwenden. Trotzdem lese ich diese Frage hier, weil das in meinem Fall nicht möglich ist.
Sie können es (noch) nicht mit String-Interpolation tun. Ihre beste Wahl wird immer noch die NSString-Formatierung sein:
println(NSString(format:"%.2f", sqrt(2.0)))
Aus Python zu extrapolieren, scheint eine vernünftige Syntax zu sein:
@infix func % (value:Double, format:String) -> String {
return NSString(format:format, value)
}
Damit können Sie sie verwenden als:
M_PI % "%5.3f" // "3.142"
Sie können ähnliche Operatoren für alle numerischen Typen definieren. Leider habe ich keine Möglichkeit gefunden, dies mit Generika zu tun.
Swift 5 Update
Ab mindestens Swift 5 String
unterstützt direkt dieformat:
Initialisierer , sodass keine Verwendung erforderlich ist NSString
und das @infix
Attribut nicht mehr benötigt wird. Dies bedeutet, dass die obigen Beispiele wie folgt geschrieben werden sollten:
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...
Warum es so kompliziert machen? Sie können dies stattdessen verwenden:
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
Sehen Sie, wie es auf dem Spielplatz funktioniert.
PS: Lösung von: http://rrike.sh/xcode/rounding-various-decimal-places-swift/
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
Eine elegantere und allgemeinere Lösung besteht darin, den Ruby / Python- %
Operator neu zu schreiben :
// 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]
funktioniert, aber seltsamerweise "%@ %@" % ["Hello", "World"]
erhöhen can't unsafeBitCast
... Vermutlich wird das in der nächsten Version behoben.
,
ist kein gültiger Zeichenoperator in Swift und den meisten Sprachen. Und imo ist es besser, %
Operatoren zu verwenden , die bereits in anderen Sprachen vorhanden sind. Siehe developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Swift 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
Sie können NSLog in Swift weiterhin wie in Objective-C verwenden, nur ohne das @ -Zeichen.
NSLog("%.02f %.02f %.02f", r, g, b)
Edit: Nachdem ich seit einiger Zeit mit Swift gearbeitet habe, möchte ich auch diese Variation hinzufügen
var r=1.2
var g=1.3
var b=1.4
NSLog("\(r) \(g) \(b)")
Ausgabe:
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 abgerundet (_ Regel: 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
mutierende Funktionsrunde (_ Regel: 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)
Die bisher gegebenen Antworten, die die meisten Stimmen erhalten haben, basieren auf NSString-Methoden und erfordern, dass Sie Foundation importiert haben.
Nachdem Sie dies getan haben, haben Sie weiterhin Zugriff auf NSLog.
Ich denke, die Antwort auf die Frage, wenn Sie fragen, wie Sie NSLog in Swift weiterhin verwenden können, lautet einfach:
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)
hier eine "reine" schnelle Lösung
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)")
Verlängerungskraft
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)")
Ausgabe: Die Geschwindigkeit beträgt 12,3
Auch mit Rundung:
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
Verwenden Sie die folgende Methode
let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)
println(output)
Viele gute Antworten oben, aber manchmal ist ein Muster angemessener als die Art von "% .3f" Gobbledygook. Hier ist meine Einstellung mit einem 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
Hier wollte ich, dass immer 2 Dezimalstellen angezeigt werden, aber die dritte nur, wenn sie nicht Null ist.
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 ""
}
}
Was ist mit Erweiterungen für Double- und CGFloat-Typen:
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)"
}
}
}
Verwendungszweck:
let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")
Drucke: 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
Ich weiß nichts über zwei Dezimalstellen, aber hier ist, wie Sie Floats mit null Dezimalstellen drucken können. Ich würde mir also vorstellen, dass dies 2 Stellen, 3 Stellen sein können ... (Hinweis: Sie müssen CGFloat in Double konvertieren, um zu übergeben zu String (Format :) oder es wird ein Wert von Null angezeigt)
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-Beispiel: Bildschirmbreite des iOS-Geräts beim Formatieren des Floats ohne Entfernen der Dezimalstelle
print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
@ Christian Dietrich:
anstatt:
var k = 1.0
for i in 1...right+1 {
k = 10.0 * k
}
let n = Double(Int(left*k)) / Double(k)
return "\(n)"
es könnte auch sein:
let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"
[Korrektur:] Entschuldigung für die Verwirrung * - Natürlich funktioniert dies mit Doppel. Ich denke, am praktischsten (wenn Sie möchten, dass Ziffern gerundet und nicht abgeschnitten werden), wäre es ungefähr so:
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
}
Ersetzen Sie Double nur für Float, ersetzen Sie Double durch Float, pow durch powf und round durch roundf.
Update: Ich fand, dass es am praktischsten ist, den Rückgabetyp Double anstelle von String zu verwenden. Dies funktioniert genauso für die String-Ausgabe, dh:
println("Pi is roughly \(3.1415926 ~> 3)")
Drucke: Pi ist ungefähr 3.142.
Sie können es also genauso für Strings verwenden (Sie können sogar noch schreiben: println (d ~> 2)), aber Sie können es auch verwenden, um Werte direkt zu runden, dh:
d = Double(slider.value) ~> 2
oder was auch immer du brauchst ...