Precision String Format Specifier In Swift

395

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!

user3524868
quelle

Antworten:

277

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.

Anton Tcholakov
quelle
76
Das ist unnötig kompliziert. Die Antwort von Realityone funktioniert und ist viel prägnanter.
Steven Marlowe
9
Sicher, wenn Sie es nur einmal verwenden. Wenn Sie jedoch mehr Formatierungsoptionen mithilfe der Zeichenfolgeninterpolation wünschen (die viel besser lesbar ist), können Sie alle Formatierungserweiterungen an einer anderen Stelle in eine Datei einfügen und im gesamten Projekt darauf verweisen. Idealerweise sollte Apple die Formatierungsbibliothek bereitstellen.
Anton Tcholakov
2
Diese Lösung funktioniert in Swift 1.2 nicht, ohne das Ergebnis in String umzuwandeln.
Ibesora
Schön, aber nicht Swift 2 Friend.
LastMove
798

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))
Realität
quelle
9
println(String(format: "a float number: %.5f", 1.0321))
Zaph
78
Ich glaube, das ist eine bessere Antwort als die akzeptierte Antwort. Es ist dem Standard-C-Stil viel näher, printfohne dass separate Erweiterungen geschrieben werden müssen.
Keith Morris
9
Vergessen Sie nicht die "Import Foundation" oben in der Datei.
Chris Gregg
3
Dies ist besser als die akzeptierte Antwort, verwendet jedoch weiterhin Foundation-Methoden (überbrückt mit Swift).
1
Seien Sie sicherimport Foundation
NaN
125

Ich fand String.localizedStringWithFormates ziemlich gut zu arbeiten:

Beispiel:

let value: Float = 0.33333
let unit: String = "mph"

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Valentin
quelle
Die Frage hat nichts mit Handling Units zu tun. localizedStringWithFormat ist nett, aber nicht verwandt.
AmitP
Ich stimme AmitP zu, es wurde gefragt, bevor String (Format: ..., Argumente: ...) verfügbar war
Valentin
84

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
fatihyildizhan
quelle
Dies wird nicht kompiliert (unter Verwendung von 3.0.2 in der Swift-Sandbox von IBM):Col 16: 'init' has been renamed to 'init(describing:)'
Peter Dillinger
@PeterDillinger Sie übergeben einen optionalen anstelle eines nicht verpackten Werts.
Michael
63

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

SWIFT 3.1 Update

extension Float {
    func string(fractionDigits:Int) -> String {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = fractionDigits
        formatter.maximumFractionDigits = fractionDigits
        return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
    }
}
Donn
quelle
12
Ich wünschte, mehr Leute würden NSNumberFormatterdiese 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).
Rob
3
Die einzige Verbesserung, die ich sehen möchte, ist das Speichern des Formatierers für eine bestimmte Anzahl - die Erstellung der NSNumberFormatters ist teuer.
Kendall Helmstetter Gelner
1
genau das, wonach ich gesucht habe! Vielen Dank
Gunjot Singh
Ich weiß, dass dies eine etwas alte Frage ist, die sich jedoch NSNumberFormatternur 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.
Promacuser
44

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 Stringunterstützt direkt dieformat: Initialisierer , sodass keine Verwendung erforderlich ist NSStringund das @infixAttribut 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"
David Berry
quelle
Wo haben Sie die Syntax "NSString (Format:" formatString ", val)" gefunden? Ich sehe es nicht im iBooks-Dokument von Apple.
Duncan C
1
Es ist das gleiche wie das Konstruieren eines objektiven Objekts aus schnell. Es ist die schnelle Version von[NSString stringWithFormat...
David Berry
Erwischt. Im Swift iBook bin ich noch nicht so weit gekommen.
Duncan C
IIRC, das nicht im Swift iBook enthalten war. Es war in einer der WWDC-Sitzungen.
Schnelle
2
Wenn Sie% wie in Python implementiert haben, sollte es umgekehrt sein. "% 5.3f"% M_PI
Andy Dent
16

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/

Steyn Viljoen
quelle
Dies ist bei weitem die beste Lösung, ich verstehe nicht, wie das nicht oben ist.
pjtnt11
7
nitpicky thing .. 1.500000000 wäre nur "1.5" und nicht "1.50"
styler1972
13
import Foundation

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

Verwendungszweck

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

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]
Vincent Guerci
quelle
Leider stirbt dies in Beta 6: Schwerwiegender Fehler: Kann nicht sicher sein, dass BitCast zwischen Typen unterschiedlicher Größe wechselt.
Binarymochi
@binarymochi Mit Beta 6: "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.
Vincent Guerci
Könnten Sie ',' zu dem verwendeten Operator machen? '@infix func, (…', und schreibe dann deine Strings wie "Hallo% @, das ist pi:% .2f", ["du", M_PI])?
Rick
@ Rick nein, das kannst du nicht, ,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/…
Vincent Guerci
8

Swift 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
onmyway133
quelle
let temp: Float = div * 100 let string = String (Format: "% .2f", Gebietsschema: Locale.current, Argumente: temp) gibt mir einen Fehler. Der Wert vom Typ 'Float' kann nicht in den erwarteten Argumenttyp '[CVarArg] konvertiert werden
Chandni
Sie müssen diese 15.123 in ein Array setzen, damit es funktioniert
Dorian Roy
3
für mich funktioniert: let string = String (Format: "% .2f", myString)
Grzegorz R. Kulesza
6

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
hol
quelle
6

Einzelheiten

  • Xcode 9.3, Swift 4.1
  • Xcode 10.2.1 (10E1001), Swift 5

Lösung 1

func round () -> Double

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

mutierende Funkrunde ()

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

Lösung 2

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

Verwendungszweck

_ = 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)

Vollständige Probe

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)

Ausgabe

===========================
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
Wassili Bodnarchuk
quelle
4
extension Double {
  func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
     let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
     return Double(formattedString)!
     }
 }

 1.3333.formatWithDecimalPlaces(2)
Lucas Farah
quelle
3

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

fqdn
quelle
3
//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)
Ravi Kumar
quelle
2

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)")
Christian Dietrich
quelle
2

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

Muhammad Aamir Ali
quelle
2

weniger Schreibweise:

func fprint(format: String, _ args: CVarArgType...) {
    print(NSString(format: format, arguments: getVaList(args)))
}
Gipfel
quelle
1

Auf diese Weise können Sie auch einen Operator erstellen

operator infix <- {}

func <- (format: String, args:[CVarArg]) -> String {
    return String(format: format, arguments: args)
}

let str = "%d %.1f" <- [1453, 1.123]
otello
quelle
1

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
ChikabuZ
quelle
1

Verwenden Sie die folgende Methode

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

println(output)
Ramkumar Chintala
quelle
1

Eine Version von Vincent Guercis Ruby / Python% -Operator, aktualisiert für Swift 2.1:

func %(format:String, args:[CVarArgType]) -> String {
  return String(format:format, arguments:args)
}

"Hello %@, This is pi : %.2f" % ["World", M_PI]
Paul King
quelle
1

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.

AlexT
quelle
1

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 ""
    }
}
Jason
quelle
1

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

M Wilm
quelle
0
@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
user3778351
quelle
0

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))
}
klares Licht
quelle
0

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)))
Gunnar Forsgren - Mobimation
quelle
-1

@ 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 ...

Stuepfnick
quelle
Dies ist offensichtlich als Kommentar gedacht. Ich verstehe, dass Sie mehr Platz benötigen, um einen Punkt zu verdeutlichen, und es ist wertvoll, aber wenn Sie ihn als vollwertige Antwort schreiben wollen, machen Sie ihn unabhängig voneinander nützlich. Sie könnten zum Beispiel den vollständigen Code hinzufügen und dann eine Bemerkung machen und Christian bestätigen.
Jaime Gómez
@ Jaime Gómez: Ich darf die obige Antwort nicht kommentieren. Trotzdem hatte ich eine falsche Interpretation *. Ich weiß nicht, ob es sich lohnt, behalten zu werden oder gelöscht werden sollte. Natürlich kann dies auf ähnliche Weise nur zum Runden verwendet werden (ohne String-Konvertierung) und kann leicht in andere Programmiersprachen übersetzt werden. * Ich habe angenommen, dass es mit Double auf ungefähr 8 Stellen gerundet wird, was natürlich ein Fehler war, weil ich es mit Float gerundet und das versehentlich in Double konvertiert habe.
Stuepfnick
PS: Ich würde es vorziehen, ähnliche Methoden eher für das Runden im Allgemeinen zu verwenden, nicht für die String-Ausgabe. Geben Sie daher den Typ Double (& reguläre Methode?) Zurück wird in Ordnung sein, wie "0.1", aber wenn Sie diesen Float in Double und dann in String * konvertieren, wird es sein: "0.100000001490116", da Float nicht in der Lage ist, 0.1 genau zu speichern, nur sehr nahe. Ich denke, es ist dasselbe mit Double, nur mit doppelter Genauigkeit ;) Konvertiere also immer vor dem Runden in Double , damit es so genau wie möglich ist und auch in String fine konvertiert.
Stuepfnick
PPS: Natürlich ist es bei Return Type Double manchmal etwas anders, dh wenn Sie einen Beschriftungstext festlegen müssen, müssen Sie schreiben: myLabel.text = "\ (d ~> 2)" anstelle von nur: myLabel. text = d ~> 2 , aber ich denke immer noch, dass die Funktion auf diese Weise praktischer ist. (Natürlich kann jeder tun, was er will, nur meine Gedanken ...)
Stuepfnick
-2

verwenden

CGFloat 

oder

Float.roundTo(places:2)
Nicson
quelle
1
CGFloat hat keine Mitgliederrunde zu
Chandni