Kann mir jemand sagen, wie man einen Doppelwert in Swift auf x Dezimalstellen rundet?
Ich habe:
var totalWorkTimeInHours = (totalWorkTime/60/60)
Mit totalWorkTime
einem NSTimeInterval (doppelt) auf dem zweiten Platz.
totalWorkTimeInHours
wird mir die Stunden geben, aber es gibt mir die Zeit in einer so langen, genauen Zahl, z. B. 1,543240952039 ......
Wie runde ich dies beim Drucken auf beispielsweise 1,543 ab totalWorkTimeInHours
?
ios
swift
double
nstimeinterval
Leighton
quelle
quelle
round(_:)
,Double
round()
,NSString
initializer,String
initializer,NumberFormatter
, Doppel Verlängerung oder sogarNSDecimalNumber
undDecimal
.Antworten:
Sie können die Swift-
round
Funktion verwenden, um dies zu erreichen.Um a
Double
mit einer Genauigkeit von 3 Stellen zu runden , multiplizieren Sie es zuerst mit 1000, runden Sie es und dividieren Sie das gerundete Ergebnis durch 1000:Anders als jede Art von
printf(...)
oderString(format: ...)
Lösungen ist das Ergebnis dieser Operation noch vom TypDouble
.EDIT:
In Bezug auf die Kommentare, dass es manchmal nicht funktioniert, lesen Sie bitte dies:
Was jeder Programmierer über Gleitkomma-Arithmetik wissen sollte
quelle
let rate = 9.94999999999; Double(round(rate * 100) / 100);
Ausgabe: Funktioniert9.94999999999, 9.949999999999999
nur für den Druck, aber wie kann ich sie einer Variablen zuweisen?Erweiterung für Swift 2
Eine allgemeinere Lösung ist die folgende Erweiterung, die mit Swift 2 und iOS 9 funktioniert:
Erweiterung für Swift 3
In Swift 3
round
wird ersetzt durchrounded
:Beispiel, das Double auf 4 Dezimalstellen gerundet zurückgibt:
quelle
round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0)
Rückgabe8.460000000000001
. Dasselbe mit Float zu tun, zumindest in diesem Szenario , scheint tatsächlich zu funktionieren:round(Float(8.46) * pow(10.0, 3.0)) / pow(10.0, 3.0)
Erträge8.46
. Nur etwas Bemerkenswertes.No '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule'
Um rund
totalWorkTimeInHours
3 Ziffern für das Drucken, verwenden Sie denString
Konstruktor , der eine nimmtformat
string:quelle
String(format: "%.3f", 1.23489)
druckt1.235
Mit Swift 5 können Sie je nach Bedarf einen der 9 folgenden Stile auswählen , um ein abgerundetes Ergebnis aus a zu erhalten
Double
.# 1. Mit
FloatingPoint
rounded()
MethodeIm einfachsten Fall können Sie die
Double
rounded()
Methode verwenden.# 2. Mit
FloatingPoint
rounded(_:)
Methode#3. Verwenden der Darwin-
round
FunktionFoundation bietet eine
round
Funktion über Darwin.# 4. Verwenden einer
Double
benutzerdefinierten Erweiterungsmethode, die mit Darwinround
undpow
Funktionen erstellt wurdeWenn Sie den vorherigen Vorgang viele Male wiederholen möchten, kann eine Umgestaltung Ihres Codes eine gute Idee sein.
# 5. Mit
NSDecimalNumber
rounding(accordingToBehavior:)
MethodeBietet bei Bedarf
NSDecimalNumber
eine ausführliche, aber leistungsstarke Lösung zum Runden von Dezimalzahlen.# 6. Mit
NSDecimalRound(_:_:_:_:)
Funktion# 7. Mit
NSString
init(format:arguments:)
initializerWenn Sie eine
NSString
von Ihrem Rundungsvorgang zurückgeben möchten , ist die Verwendung desNSString
Initialisierers eine einfache, aber effiziente Lösung.# 8. Mit
String
init(format:_:)
initializerSwifts
String
Typ ist mit derNSString
Klasse der Foundation verbunden . Daher können Sie den folgenden Code verwenden, um aString
von Ihrer Rundungsoperation zurückzugeben:# 9. Verwenden von
NumberFormatter
Wenn Sie erwarten, eine
String?
von Ihrem Rundungsvorgang zu erhalten,NumberFormatter
bietet eine hochgradig anpassbare Lösung.quelle
Decimal
, die gebührenfrei überbrückt istNSDecimalNumber
.Decimal
ist der Swift elegantere Unterstützung nativer Typ und Angebote für native Operatoren wie+
,-
etc.NSDecimalRound(_:_:_:_:)
Funktion aktualisiert . Vielen Dank.NumberFormatter
die letzte Option ist, während es die erste sein sollte, um Benutzern Zahlen zu präsentieren. Keine andere Methode generiert korrekt lokalisierte Zahlen.In Swift 2.0 und Xcode 7.2:
Beispiel:
quelle
Dies ist ein voll funktionsfähiger Code
Swift 3.0 / 4.0 / 5.0, Xcode 9.0 GM / 9.2 und höher
Ausgabe - 123
Ausgabe - 123.3
Ausgabe - 123,33
Ausgabe - 123.326
quelle
Aufbauend auf Yogis Antwort ist hier eine Swift-Funktion, die den Job erledigt:
quelle
In Swift 3.0 und Xcode 8.0:
Verwenden Sie diese Erweiterung wie folgt:
quelle
Swift 4, Xcode 10
quelle
Der Code für bestimmte Ziffern nach Dezimalstellen lautet:
Hier weist% .3f den Swift an, diese Zahl auf 3 Dezimalstellen zu runden. Wenn Sie eine doppelte Zahl wünschen, können Sie diesen Code verwenden:
var roundedString = Double(String(format: "%.3f", b))
quelle
Verwenden Sie die integrierte Foundation Darwin-Bibliothek
SWIFT 3
Verwendungszweck:
Ausgänge: 12.988
quelle
Ein praktischer Weg kann die Verwendung einer Erweiterung vom Typ Double sein
Verwendungszweck:
quelle
Wenn Sie
Double
Werte runden möchten, möchten Sie möglicherweise Swift verwenden,Decimal
damit keine Fehler auftreten, die auftreten können, wenn Sie versuchen, mit diesen gerundeten Werten zu rechnen. Wenn Sie verwendenDecimal
, kann es Dezimalwerte dieses gerundeten Gleitkommawerts genau darstellen.So können Sie tun:
Dann können Sie den gerundeten
Decimal
Wert wie folgt erhalten:Wenn Sie es mit einer bestimmten Anzahl von Dezimalstellen anzeigen möchten (und die Zeichenfolge für das aktuelle Gebietsschema des Benutzers lokalisieren möchten), können Sie Folgendes verwenden
NumberFormatter
:quelle
(4.81).roundedDecimal(to: 2, mode: .down)
wird 4,8 statt 4,81 zurückgeben,Decimal(string: self.description)!
für eine genaue verwendendecimalValue
Double
(es wird4.8099999999999996
). Ich würde jedoch von der Verwendung abratendescription
(da die verwendete Rundung nicht dokumentiert ist und Änderungen vorbehalten ist). Wenn Sie wirklich dezimalgenau rechnen möchten, sollten Sie diesDouble
vollständig vermeiden und stattdessenDecimal
direkt verwenden (z . B.Decimal(sign: .plus, exponent: -2, significand: 481)
oderDecimal(string: "4.81")
. Aber nicht verwendendescription
.description
Methode ist weder dokumentiert noch garantiert. Außerdem ist es nicht lokalisiert. IMHO ist es ein Fehler,description
etwas anderes als Protokollierungszwecke zu verwenden. Ich würde entwederDecimal
durchgehend verwenden, ganz vermeidenDouble
oder einfach einen anderen Rundungsmodus verwenden. Wenn Sie müssen, verwenden Sie auch Ihre eigene lokalisierte Methode, die einen Algorithmus im Grisu-Stil verwendet (dies erscheint jedoch unnötig, wenn Sie wissen, wie viele Dezimalstellen Sie runden möchten). Aber ich würde es vermeiden, mich auf dieses Nebenverhalten von zu verlassendescription
.Dies ist eine Art lange Problemumgehung, die sich als nützlich erweisen kann, wenn Ihre Anforderungen etwas komplexer sind. Sie können in Swift einen Zahlenformatierer verwenden.
Angenommen, Ihre Variable, die Sie drucken möchten, ist
Dadurch wird sichergestellt, dass es im gewünschten Format zurückgegeben wird:
Das Ergebnis hier ist also "3.6" (gerundet). Dies ist zwar nicht die wirtschaftlichste Lösung, aber ich gebe sie an, weil das OP das Drucken erwähnte (in diesem Fall ist ein String nicht unerwünscht) und weil diese Klasse das Einstellen mehrerer Parameter ermöglicht.
quelle
ich würde ... benutzen
und ändern Sie .3f in eine beliebige Anzahl von Dezimalzahlen, die Sie benötigen
quelle
Entweder:
Verwenden von
String(format:)
:Typecast
Double
toString
mit%.3f
Formatbezeichner und dann zurück zuDouble
Oder erweitern Sie
Double
, um N-Dezimalstellen zu behandeln:Nach Berechnung
mit 10 ^ 3 multiplizieren, runden und dann durch 10 ^ 3 dividieren ...
Oder erweitern Sie
Double
, um N-Dezimalstellen zu behandeln:quelle
Dies ist ein flexiblerer Algorithmus zum Runden auf N signifikante Stellen
Swift 3-Lösung
quelle
Der beste Weg, eine doppelte Eigenschaft zu formatieren, ist die Verwendung der vordefinierten Apple-Methoden.
FloatingPointRoundingRule ist eine Aufzählung mit folgenden Möglichkeiten
Aufzählungsfälle:
Fall wegFromZero Runden Sie auf den nächsten zulässigen Wert, dessen Größe größer oder gleich der der Quelle ist.
Fall unten Runden Sie auf den nächsten zulässigen Wert ab, der kleiner oder gleich der Quelle ist.
Fall zu NearestOrAwayFromZero Runde auf den nächsten zulässigen Wert; Wenn zwei Werte gleich nahe beieinander liegen, wird der mit der größeren Größe gewählt.
Fall zu NearestOrEven Round auf den nächsten zulässigen Wert; Wenn zwei Werte gleich nahe beieinander liegen, wird der gerade gewählt.
Fall in Richtung Null Runden Sie auf den nächsten zulässigen Wert, dessen Größe kleiner oder gleich der der Quelle ist.
case up Runden Sie auf den nächsten zulässigen Wert, der größer oder gleich der Quelle ist.
quelle
Runden Sie einen Doppelwert auf x Dezimalzahl
NO. von Nachkommastellen
quelle
Nicht Swift, aber ich bin mir sicher, dass Sie auf die Idee kommen.
quelle
Dies scheint in Swift 5 zu funktionieren.
Sehr überrascht, dass es dafür noch keine Standardfunktion gibt.
// Abschneiden von Doppel- auf n-Dezimalstellen mit Rundung
quelle
Sie können diese Erweiterung hinzufügen:
und nenne es so:
quelle
Verwenden Sie Decimal, um Float-Fehler zu vermeiden
Ex.
1075,58 Runden auf 1075,57 bei Verwendung von Float mit Skalierung: 2 und .down
1075,58 Runden auf 1075,58 bei Verwendung von Decimal mit Skalierung: 2 und .down
quelle
Ich habe mich gefragt, ob es möglich ist, die Eingabe eines Benutzers zu korrigieren. Das heißt, wenn sie drei Dezimalstellen anstelle von zwei für einen Dollarbetrag eingeben. Sagen Sie 1.111 statt 1.11. Können Sie das Problem durch Runden beheben? Die Antwort lautet aus vielen Gründen nein! Mit Geld würde alles über 0,001 irgendwann Probleme in einem echten Scheckheft verursachen.
Hier ist eine Funktion, um die Benutzereingabe nach dem Zeitraum auf zu viele Werte zu überprüfen. Aber was erlaubt 1., 1.1 und 1.11.
Es wird davon ausgegangen, dass der Wert bereits auf erfolgreiche Konvertierung von einem String in einen Double überprüft wurde.
quelle
quelle
Verwendungszweck :
quelle
Hier ist eine für SwiftUI, wenn Sie ein Textelement mit dem Zahlenwert benötigen.
quelle