Aus irgendeinem Grund geben mir einige Double-Dateien in meiner Swift-App Probleme beim Konvertieren in NSNumber, während andere nicht funktionieren. Meine App muss Doubles mit 2 Dezimalstellen (Preisen) in NSNumbers konvertieren, damit sie mit Core Data gespeichert und abgerufen werden können. Zum Beispiel würden einige bestimmte Preise wie 79,99 zu 99,98999999999999 auswerten, es sei denn, sie wurden speziell mit der DoubleValue-Methode von NSNumber formatiert.
Hier selectedWarranty.price = 79.99 wie im Debugger
gezeigt %Vor%Ich habe einige Druckanweisungen programmiert, um zu zeigen, wie die Konvertierung funktioniert
%Vor%Kann jemand erklären, ob es einen Grund gibt, warum der Initialisierer nicht sicher zwei Dezimalstellen für jede Zahl behalten kann? Ich würde wirklich gerne die Preise in Core Data speichern, so wie sie sein sollten. Die Formatierung bei jeder Anzeige klingt nicht sehr praktisch.
UPDATE : Konvertiert Core Data-Objekt zu Typ NSDecimalNumber durch Datenmodell, 79,99 und 99,99 ist kein Problem mehr, aber jetzt leichter zu handhabendes Problem mit verschiedenen Zahlen ...
%Vor% Erstens verwirren Sie einige Begriffe. 79.98999999999999
ist eine höhere Genauigkeit als 79.99
(es hat eine längere Dezimal-Erweiterung), aber eine geringere Genauigkeit (es weicht vom wahren Wert ab).
Zweitens speichert NSNumber weder 79.99
noch 79.98999999999999
. Es speichert die Größe des Wertes gemäß dem IEEE 754
Standard. Was Sie sehen, ist wahrscheinlich die Konsequenz der Drucklogik, die angewendet wird, um diese Größe in eine lesbare Zahl umzuwandeln. In jedem Fall sollten Sie sich nicht auf Float
oder Double
verlassen, um Werte mit einer festen Genauigkeit zu speichern. Aufgrund ihrer Natur opfern sie Präzision, um eine größere Reichweite von darstellbaren Werten zu erhalten.
Sie wären viel besser in der Lage, Preise als Int
von Cents oder als NSDecimalNumber
darzustellen.
Siehe Warum nicht Double oder Float zur Darstellung der Währung verwenden?
So funktioniert Double überall. Wenn Sie nur 2 Dezimalstellen benötigen, sollten Sie integer / long verwenden und stattdessen einen Punkt nach der zweiten Ziffer hinzufügen, wenn der Wert angezeigt werden muss.