Ich verwende NSDecimalNumber, um einen Wert für die Währung zu speichern. Ich versuche eine Methode namens "Cents" zu schreiben, die den Dezimalteil der Zahl als NSString mit einer führenden 0 zurückgibt, wenn die Zahl & lt; 10. Also im Grunde
%Vor%Und ich versuche eine Methode zu erstellen, die 01, 02, etc ... bis 99 als String zurückgibt. Ich kann nicht herausfinden, wie man die Mantisse als String in diesem Format zurückgibt. Ich habe das Gefühl, dass mir eine bequeme Methode fehlt, aber ich habe mir die Dokumentation noch einmal angeschaut und sehe nichts, was mich herausspringt.
Update: Dies ist eine relativ alte Antwort, aber es sieht so aus, als würden die Leute es immer noch finden. Ich möchte dies auf Korrektheit aktualisieren - ich habe ursprünglich die Frage beantwortet, wie ich einfach demonstrierte, wie man bestimmte Dezimalstellen aus einem double
herausziehen kann, aber ich befürworte dies nicht als eine Möglichkeit, Währungsinformationen darzustellen.
Nie verwenden Gleitkommazahlen, um Währungsinformationen darzustellen. Sobald Sie anfangen, mit Dezimalzahlen zu arbeiten (wie Sie es mit Dollars mit Cent tun würden), führen Sie mögliche Gleitkommafehler in Ihren Code ein. Ein Computer kann nicht alle Dezimalwerte genau darstellen ( 1/100.0
, z. B. 1 Cent, wird auf meinem Computer als 0.01000000000000000020816681711721685132943093776702880859375
dargestellt). Abhängig davon, welche Währungen Sie repräsentieren möchten, ist es immer korrekter, eine Menge in Bezug auf ihren Basisbetrag (in diesem Fall Cent) zu speichern.
Wenn Sie Ihre Dollarwerte in ganzzahligen Centwerten speichern, werden Sie bei den meisten Operationen nie auf Gleitkommafehler stoßen, und es ist trivial einfach, Cent in Dollars für die Formatierung umzuwandeln. Wenn Sie zum Beispiel Steuern anwenden oder Ihren Cent-Wert mit einem double
multiplizieren möchten, tun Sie dies, um einen double
-Wert zu erhalten, wenden Sie Runden des Bankers , um auf den nächsten Cent zu runden und zurück in eine Ganzzahl zu konvertieren.
Es wird komplizierter, wenn Sie versuchen, mehrere Währungen zu unterstützen, aber es gibt Möglichkeiten, damit umzugehen.
tl; dr Verwenden Sie keine Gleitkommazahlen, um die Währung darzustellen, und Sie werden viel glücklicher und korrekter sein. NSDecimalNumber
kann genau (und genau) Dezimalwerte darstellen, aber sobald Sie in double
/ float
konvertieren, laufen Sie Gefahr, Gleitkommafehler einzuführen.
Dies kann relativ einfach gemacht werden:
double
-Wert der Dezimalzahl (dies funktioniert, vorausgesetzt, die Zahl ist nicht zu groß, um sie in einem Doppel zu speichern). double
auf eine ganze Zahl umgewandelt. (Dies ist eine allgemeine Formel für das Arbeiten mit allen Dezimalzahlen - die Arbeit mit NSDecimalNumber
erfordert nur ein wenig Klebstoffcode, um es zum Laufen zu bringen).
In der Praxis würde es so aussehen (in einer Kategorie NSDecimalNumber
):
Dies ist eine sicherere Implementierung, die mit Werten arbeitet, die nicht in double
passen:
Dies druckt 01
:
Ich stimme der Methode von Itai Ferber nicht zu, da die Verwendung von doubleValue
methode von NSNumber
zu einem Verlust der Genauigkeit wie 1.60 & gt; & gt; 1.5999999999, so wird Ihr Cents-Wert "59" sein. Stattdessen schneide ich "dollars" / "cents" aus string, erhalten mit NSNumberFormatter
:
Ich habe einen anderen Ansatz. Es funktioniert für mich, aber ich bin mir nicht sicher, ob es irgendwelche Probleme verursachen könnte? Ich lasse NSDecimalNumber den Wert direkt zurückgeben, indem ich einen ganzzahligen Wert zurückließe ...
e.G .:
%Vor%Wäre dieser Ansatz teurer, da ich NSDecimalNumber zweimal konvertiere?
Schnelle Version, mit Bonusfunktion, um auch nur den Dollar-Betrag zu erhalten.
%Vor%Tests:
%Vor%Tags und Links objective-c xcode mantissa nsdecimalnumber