it-swarm.com.de

Wie benutze ich NSDecimalNumber?

Ich baue eine App, die Berechnungen zum Geld durchführen muss.

Ich frage mich, wie man NSDecimalNumber richtig verwendet, vor allem, wie man es aus ganzen Zahlen, Floaten und Doubles initialisiert?

Ich fand es einfach, die -decimalNumberWithString:-Methode zu verwenden. Die -initWith...-Methoden sind entmutigt, so dass nur diejenigen mit Mantisse übrig blieben, aber in keiner der 7 Sprachen, die ich vorher verwendete, brauchte ich das, also weiß ich nicht, was da hingelegt wird ...

43
mamcx

Verwenden Sie NICHT die +numberWith...-Methoden von NSNumber, um NSDecimalNumber-Objekte zu erstellen. Sie werden als NSNumber-Objekte zurückgegeben und können nicht als NSDecimalNumber-Instanzen fungieren.

Dies wird in diesem Thread von Bill Bumgarner, einem Entwickler bei Apple, erklärt. Ich möchte Sie dazu auffordern, einen Fehler gegen dieses Verhalten einzureichen, indem Sie auf den Fehler rdar: // 6487304 verweisen.

Als Alternative sind dies alle geeigneten Methoden, um eine NSDecimalNumber zu erstellen:

+ (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa
                     exponent:(short)exponent isNegative:(BOOL)flag;
+ (NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)dcm;
+ (NSDecimalNumber *)decimalNumberWithString:(NSString *)numberValue;
+ (NSDecimalNumber *)decimalNumberWithString:(NSString *)numberValue locale:(id)locale;

+ (NSDecimalNumber *)zero;
+ (NSDecimalNumber *)one;
+ (NSDecimalNumber *)minimumDecimalNumber;
+ (NSDecimalNumber *)maximumDecimalNumber;
+ (NSDecimalNumber *)notANumber;

Wenn Sie einfach eine NSDecimalNumber von einer float- oder int-Konstante wünschen, versuchen Sie Folgendes:

NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithDecimal:
                             [[NSNumber numberWithFloat:2.75f] decimalValue];
82
Ashley Clark

Der richtige Weg ist eigentlich dies zu tun:

NSDecimalNumber *floatDecimal = [[[NSDecimalNumber alloc] initWithFloat:42.13f] autorelease];
NSDecimalNumber *doubleDecimal = [[[NSDecimalNumber alloc] initWithDouble:53.1234] autorelease];
NSDecimalNumber *intDecimal = [[[NSDecimalNumber alloc] initWithInt:53] autorelease];

NSLog(@"floatDecimal floatValue=%6.3f", [floatDecimal floatValue]);
NSLog(@"doubleDecimal doubleValue=%6.3f", [doubleDecimal doubleValue]); 
NSLog(@"intDecimal intValue=%d", [intDecimal intValue]);

Mehr Infos hier .

31
orj

Aus Designgründen sollten Sie die Konvertierung von NSDecimalNumber oder NSDecimals in und aus den Werten int, float und double vermeiden, und zwar aus den gleichen Gründen, in denen NSDecimalNumbers empfohlen wird: Verlust der Genauigkeit und Probleme mit der Darstellung von binären Gleitkommadarstellungen. Ich weiß, manchmal ist es unvermeidlich (Eingabe eines Schiebereglers, Durchführung trigonometrischer Berechnungen usw.), aber Sie sollten versuchen, Eingaben von Benutzern als NSStrings zu verwenden und dann initWithString: locale: oder decimalNumberWithString: locale: zu verwenden, um die NSDecimalNumbers zu generieren. Berechnen Sie die NSDecimalNumbers und geben Sie ihre Darstellung an die Benutzer zurück oder speichern Sie sie mit descriptionWithLocale: in SQLite (oder wo auch immer) als Zeichenfolgenbeschreibung.

Wenn Sie Eingaben von einem Int, Float oder Double vornehmen müssen, können Sie etwa Folgendes tun:

int myInt = 3;
NSDecimalNumber *newDecimal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%d", myInt]];

oder Sie könnten dem Vorschlag von Ashley folgen, um sicherzustellen, dass Sie in der dezimalen Konstruktion sicher sind.

6
Brad Larson

Eine kleine Ergänzung: Wenn Sie NSDecimalNumber von einem String aus initiieren, kann es nützlich sein, auch ein Gebietsschema festzulegen. Wenn Ihre Zeichenfolge beispielsweise ein Komma als decimal separator enthält. 

self.order.amount = [NSDecimalNumber decimalNumberWithString:self.amountText locale:[NSLocale currentLocale]];
0
wzbozon