2009-01-17 58 views
43

我正在構建一個需要對錢進行計算的應用程序。如何使用NSDecimalNumber?

我不知道如何正確使用NSDecimalNumber,特別是如何初始化它從整數,浮動&雙打?

我只發現很容易使用-decimalNumberWithString:方法。該-initWith...方法都望而卻步,這樣只剩下尾數的,但從來沒有在任何的7種語言我用以前做我需要的,所以我不知道什麼是放在那裏......

回答

80

使用NSNumber+numberWith...方法來創建NSDecimalNumber對象。聲明它們返回NSNumber對象,並且不保證其功能爲NSDecimalNumber實例。

這是由蘋果開發人員Bill Bumgarner在thread中解釋的。我鼓勵你提交一個針對此行爲的bug,引用bug rdar:// 6487304。

作爲替代,這些都是一種適當的方法用於創建一個NSDecimalNumber

+ (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; 

如果你只是想從一個floatint不斷嘗試這樣的NSDecimalNumber

NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithDecimal: 
          [[NSNumber numberWithFloat:2.75f] decimalValue]; 
+4

此外,正如下面的@orj所示,使用`-initWithFloat:`,`-initWithDouble:`和其他方法也是正確的。這些被聲明爲返回`id`,並且我剛剛證實他們確實在Snow Leopard上返回了一個`NSDecimalNumber`。 – 2011-09-29 08:55:34

6

設計方面,您應該儘量避免將NSDecimalNumber或NSDecimals轉換爲int,float和double值,原因與建議您使用NSDecimalNumbers:lo精度和二進制浮點表示問題的ss。我知道,有時它是不可避免的(從滑塊輸入數據,做三角函數計算等),但是你應該嘗試從用戶那裏獲取NSString的輸入,然後使用initWithString:locale:或者decimalNumberWithString:locale:來生成NSDecimalNumbers。用NSDecimalNumbers完成所有數學計算,並將其表示形式返回給用戶,或者使用descriptionWithLocale:將其保存到SQLite(或任何地方)作爲其字符串描述。

如果從一個int,float或雙有輸入,你可以這樣做以下:

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

,或者你可以遵循阿什利的建議,以確保你在小數施工安全。

30

正確的方法實際上是要做到這一點:

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]); 

查看更多信息here