残念ながら、AppleはNSDecimal構造体に値を入れる簡単な方法を提供していません。構造体の定義自体は、NSDecimal.hヘッダーにあります。
typedef struct {
signed int _exponent:8;
unsigned int _length:4; // length == 0 && isNegative -> NaN
unsigned int _isNegative:1;
unsigned int _isCompact:1;
unsigned int _reserved:18;
unsigned short _mantissa[NSDecimalMaxSize];
} NSDecimal;
しかし、構造体が値を保持する方法をリバースエンジニアリングしようとすることを回避するかどうかはわかりません。構造体のフィールドの下線は、これらが非公開であり、変更される可能性があることを示しています。低レベルのNSDecimal関数に多くの変更が加えられるとは思いませんが、ある時点で問題が発生するのではないかと心配しています。
そのため、浮動小数点数からNSDecimalを初期化するのは、説明した方法で行うのが最適です。ただし、浮動小数点値を使用すると、NSDecimalを使用して得た精度が失われ、浮動小数点エラーが発生する可能性があることに注意してください。
私は常に高精度の計算でNSDecimalsのみを操作し、NSStringを取り込んでエクスポートし、これらの値を外部と交換します。NSStringに基づいてNSDecimalを作成するには、CorePlotフレームワークで採用しているアプローチを使用できます。
NSDecimal CPDecimalFromString(NSString *stringRepresentation)
{
NSDecimal result;
NSScanner *theScanner = [[NSScanner alloc] initWithString:stringRepresentation];
[theScanner scanDecimal:&result];
[theScanner release];
return result;
}
NSDecimalNumberの代わりにNSScannerを使用する-initWithString:locale:
と、ベンチマークで約90%高速になります。