私はお金の計算を実行する必要があるアプリを構築しています。
NSDecimalNumberを適切に使用する方法、特に整数、浮動小数点数、倍精度数から初期化する方法を疑問に思いますか?
-decimalNumberWithString:
メソッドを使用するのは簡単だとわかりました。 -initWith...
メソッドは推奨されないので仮数だけが残りますが、以前に使用した7つの言語のいずれにおいても必要なことはなかったので、何がそこにあるのかわかりません...
Do[〜#〜] not [〜#〜]use NSNumber
's +numberWith...
メソッドはNSDecimalNumber
オブジェクトを作成します。これらはNSNumber
オブジェクトを返すように宣言されており、NSDecimalNumber
インスタンスとして機能することは保証されていません。
これはAppleの開発者であるBill Bumgarnerが thread で説明しています。バグ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;
NSDecimalNumber
またはfloat
定数からint
が必要な場合は、次のようなものを試してください。
NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithDecimal:
[[NSNumber numberWithFloat:2.75f] decimalValue];
正しい方法は、実際にこれを行うことです。
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]);
詳細情報を参照してください こちら 。
NSDecimalNumbersを使用することをお勧めするのと同じ理由で、NSDecimalNumberまたはNSDecimalsとint、float、doubleの値の変換を避けるように、設計上は、精度の損失とバイナリ浮動小数点表現の問題を回避する必要があります。避けられないこともあります(スライダーからの入力、三角法の計算など)が、ユーザーからの入力をNSStringsとして取得し、initWithString:locale:またはdecimalNumberWithString:locale:を使用してNSDecimalNumbersを生成する必要があります。 NSDecimalNumbersを使用してすべての計算を行い、その表現をユーザーに返すか、descriptionWithLocale:を使用して文字列の説明としてSQLite(またはどこでも)に保存します。
Int、float、またはdoubleから入力する必要がある場合、次のようなことができます。
int myInt = 3;
NSDecimalNumber *newDecimal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%d", myInt]];
または、アシュリーの提案に従って、10進法で安全であることを確認できます。
ちょっとした追加:文字列からNSDecimalNumber
を初期化する場合、ロケールを設定することも役立つかもしれません。たとえば、文字列にdecimal separator
としてカンマが含まれている場合。
self.order.amount = [NSDecimalNumber decimalNumberWithString:self.amountText locale:[NSLocale currentLocale]];