Swift - Wie entferne ich eine Dezimalstelle aus einem Gleitkommawert, wenn die Dezimalstelle gleich 0 ist?


85

Ich zeige einen Abstand mit einer Dezimalstelle an und möchte diese Dezimalstelle entfernen, falls sie gleich 0 ist (z. B. 1200,0 km). Wie kann ich das schnell tun? Ich zeige diese Nummer folgendermaßen an:

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: "%.1f", distanceFloat) + "Km"

Antworten:


130

Swift 3/4:

var distanceFloat1: Float = 5.0
var distanceFloat2: Float = 5.540
var distanceFloat3: Float = 5.03

extension Float {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

print("Value \(distanceFloat1.clean)") // 5
print("Value \(distanceFloat2.clean)") // 5.54
print("Value \(distanceFloat3.clean)") // 5.03

Swift 2 (Originalantwort)

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: distanceFloat == floor(distanceFloat) ? “%.0f" : "%.1f", distanceFloat) + "Km"

Oder als Erweiterung:

extension Float {
    var clean: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

Ich habe diese Zeile schon einmal hinzugefügt distanceFloat = floor(distanceFloat * 10) / 10und dann hat es perfekt funktioniert, danke :)
— Kali Aney

1
Für Double die Erweiterung Double {var clean: String {return self% 1 == 0? String (Format: "% .0d", self): String (self)}}
— Abo3atef

3
Dies funktioniert nicht, wenn der Float so etwas wie 3.01 ist.
— Chengsam

Was ist mit negativen Zahlen?
— Happiehappie

Es funktioniert nicht für diese 123456738.0 Nummer, die konvertierte Nummer kommt als 123456736
— Anirudha Mahale

108

Verwenden Sie NSNumberFormatter:

let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2

// Avoid not getting a zero on numbers lower than 1
// Eg: .5, .67, etc...
formatter.numberStyle = .decimal

let nums = [3.0, 5.1, 7.21, 9.311, 600.0, 0.5677, 0.6988]

for num in nums {
    print(formatter.string(from: num as NSNumber) ?? "n/a")
}

Kehrt zurück:

3

5.1

7.21

9.31

600

0,57

0,7


2
perfekt ! Dies muss oben sein
— GoodSp33d

6
für Swift 3: let formatter = NumberFormatter() formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 1 statLabel.text = formatter.string(from: value as NSNumber) ?? "n/a"
— alexxjk

1
Wie wäre es mit 0,3000, ich versuche dies zu bekommen .3; Ich habe seinen Stil festgelegtformatter.numberStyle = .decimal
— Stan Liu

@stanliu ist korrekt, wenn Sie die .decimalZahl nicht hinzufügen. Stilzahlen unter 1 werden ohne Null angezeigt. Beispiel: .5, .78 usw. Bearbeiten Sie die Antwort jetzt.
— HotFudgeSunday

Ich glaube, das ist es, was Apple vorhat, um ein solches Problem zu lösen.
— DragonCherry

55

extension ist der mächtige Weg, es zu tun.

Erweiterung :

Code für Swift 2 (nicht Swift 3 oder neuer):

extension Float {
    var cleanValue: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

Verwendung :

var sampleValue: Float = 3.234
print(sampleValue.cleanValue)

3.234

sampleValue = 3.0
print(sampleValue.cleanValue)

3

sampleValue = 3
print(sampleValue.cleanValue)

3


Eine Beispielspielplatzdatei finden Sie hier .


1
Aber 3.230000 -> 3.230000 ... wie wäre es mit "-> 3.23"?
— CHiP-love-NY

1
@ CHiP-love-NY, ich habe dich nicht verstanden.
— Ashok

1
Ich glaube, er glaubt, dass Ihre Erweiterung keine nachgestellten Nullen entfernt, aber es tut es. String (3.230000) = "3.23"
— jeffjv

33

Aktualisierung der akzeptierten Antwort für Swift 3 :

extension Float
{
    var cleanValue: String
    {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

Verwendung wäre nur:

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

Funktioniert nicht, wenn Sie dh setzen. 14.000005, konvertiert es zu 14.0
— Vetuka

@ sc13 Huh, das ist komisch, wenn du es auf 14.00000005 drückst, an welchem ​​Punkt der Float selbst 14 ohne 'cleanValue' zurückgibt. Ich denke, das hat etwas damit zu tun, wie schnell Float damit umgeht. Ich werde sehen, ob ich diesen Fehler beheben kann.
— Christopher Larsen

2
Ich erhalte die richtige Ausgabe für 14.000005, daher scheint der Kommentar zu @ sc13 veraltet oder falsch zu sein.
— Cœur

10

Befolgen Sie dieses Muster, um es in String zu formatieren

let aFloat: Float = 1.123

let aString: String = String(format: "%.0f", aFloat) // "1"
let aString: String = String(format: "%.1f", aFloat) // "1.1"
let aString: String = String(format: "%.2f", aFloat) // "1.12"
let aString: String = String(format: "%.3f", aFloat) // "1.123"

Folgen Sie diesem Muster, um es in Int umzuwandeln

let aInt: Int = Int(aFloat) // "1"

9

Sie können eine Erweiterung verwenden, wie bereits erwähnt. Diese Lösung ist jedoch etwas kürzer:

extension Float {
    var shortValue: String {
        return String(format: "%g", self)
    }
}

Anwendungsbeispiel:

var sample: Float = 3.234
print(sample.shortValue)

1
Wird scheitern für 0.00000001. Siehe Dokumentation von% g unter pubs.opengroup.org/onlinepubs/009695399/functions/printf.html : " Der verwendete Stil hängt vom konvertierten Wert ab; Stil e (oder E) darf nur verwendet werden, wenn der Exponent aus einer solchen Konvertierung resultiert ist kleiner als -4 oder größer als oder gleich der Genauigkeit. "
— Cœur

perfekt. Danke
— PhillipJacobs

7

Versuchen Sie dies in Swift 4 .

    extension CGFloat{
        var cleanValue: String{
            //return String(format: 1 == floor(self) ? "%.0f" : "%.2f", self)
            return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)//
        }
    }

// Verwendung - Wenn Sie nach (.) Punkt mehr als zwei Zeichen eingeben, wird das letzte Zeichen automatisch beschnitten und nur zwei Zeichen nach dem Punkt angezeigt.

let strValue = "32.12"
print(\(CGFloat(strValue).cleanValue)

Trimmt die Null nicht vom Wert ab 1.1: Ausgabe wird sein "1.10".
— Cœur

@ Cœur wird verwendet, um zwei Werte nach Punkt (.) Anzuzeigen. Wenn Sie nur einen Wert anzeigen möchten, verwenden Sie "return self.truncatingRemainder (dividingBy: 1) == 0? String (Format:"% .0f ", self): String (Format:"% .1f ", self) / / "
— Jaydip

Ich weiß ... Ich habe nur beschrieben, wie sich Ihr Code von anderen Antwortverhalten unterscheidet.
— Cœur

4

NSNumberFormatter ist dein Freund

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
let numberFormatter = NSNumberFormatter()
numberFormatter.positiveFormat = "###0.##"
let distance = numberFormatter.stringFromNumber(NSNumber(float: distanceFloat))!
distanceLabel.text = distance + " Km"

4

Formatierung mit maximalen Bruchstellen ohne nachgestellte Nullen

Dieses Szenario ist gut, wenn eine benutzerdefinierte Ausgabegenauigkeit gewünscht wird. Diese Lösung scheint ungefähr so ​​schnell zu sein wie die NumberFormatter + NSNumber- Lösung von MirekE , aber ein Vorteil könnte sein, dass wir hier NSObject vermeiden.

extension Double {
    func string(maximumFractionDigits: Int = 2) -> String {
        let s = String(format: "%.\(maximumFractionDigits)f", self)
        var offset = -maximumFractionDigits - 1
        for i in stride(from: 0, to: -maximumFractionDigits, by: -1) {
            if s[s.index(s.endIndex, offsetBy: i - 1)] != "0" {
                offset = i
                break
            }
        }
        return String(s[..<s.index(s.endIndex, offsetBy: offset)])
    }
}

(funktioniert auch mit extension Float, aber nicht mit dem MacOS-Typ Float80)

Verwendung: myNumericValue.string(maximumFractionDigits: 2)odermyNumericValue.string()

Ausgabe für maximumFractionDigits: 2:

1,0 → "1"
0,12 → "0,12"
0,012 → "0,01"
0,0012 → "0"
0,00012 → "0"


3

Hier ist der vollständige Code.

let numberA: Float = 123.456
let numberB: Float = 789.000

func displayNumber(number: Float) {
    if number - Float(Int(number)) == 0 {
        println("\(Int(number))")
    } else {
        println("\(number)")
    }
}

displayNumber(numberA) // console output: 123.456
displayNumber(numberB) // console output: 789

Hier ist die wichtigste Zeile im Detail.

func displayNumber(number: Float) {
  1. Entfernt die Dezimalstellen des Floats mit Int(number).
  2. Gibt die gestrippte Nummer zurück an float, um eine Operation mit auszuführen Float(Int(number)).
  3. Ruft den Dezimalstellenwert mit ab number - Float(Int(number))
  4. Überprüft, ob der Dezimalstellenwert mit leer ist if number - Float(Int(number)) == 0

Der Inhalt der if- und else-Anweisungen muss nicht erläutert werden.


In Ihrem Fall möchten Sie die Funktion zurückgeben Stringund anstelle von println(result)do return result. Ich hoffe das hilft!
— Fine Man


3

Swift 5 für Double ist dasselbe wie @ Frankies Antwort für Float

var dec: Double = 1.0
dec.clean // 1

für die Erweiterung

extension Double {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }

}

2

Dies könnte auch hilfreich sein.

extension Float {
    func cleanValue() -> String {
        let intValue = Int(self)
        if self == 0 {return "0"}
        if self / Float (intValue) == 1 { return "\(intValue)" }
        return "\(self)"
    }
}

Verwendung:

let number:Float = 45.23230000
number.cleanValue()

-1

Vielleicht stringByReplacingOccurrencesOfStringkönnte dir helfen :)

let aFloat: Float = 1.000

let aString: String = String(format: "%.1f", aFloat) // "1.0"

let wantedString: String = aString.stringByReplacingOccurrencesOfString(".0", withString: "") // "1"

Dies würde einen Wert wie 1,05 -> 15
— Starceaker

@Starceaker Nein, zuerst 1.05ausführen String(format: "%.1f", aFloat)wird 1.0, funktioniert. wenn 1.05ausführen String(format: "%.2f", aFloat)wird 1.05, und dann sollte dies tunstringByReplacingOccurrencesOfString(".00"...)
— Leo

Richtig, ich habe mich auf die letzte Zeile konzentriert. Ich dachte, Sie haben mehrere Lösungen vorgeschlagen, aber tatsächlich sind Ihre Leitungen verbunden. Mein Fehler.
— Starceaker

das ist nichts :)
— Leo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.