Konvertieren von Double in NSNumber in Swift verliert Genauigkeit [duplizieren]

8

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%     
joelrorseth 24.08.2016, 15:42
quelle

2 Antworten

9

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?

    
Alexander 24.08.2016, 15:52
quelle
1

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.

    
Anton Malyshev 24.08.2016 16:04
quelle

Tags und Links