Niestety, Apple nie zapewnia łatwych sposobów umieszczania wartości w strukturze NSDecimal. Sama definicja struct można znaleźć w nagłówku 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;
ale nie wiem, że pójdę w kółko, próbując odwrócić inżynier jak kodowanym utrzymywania wartości. Podkreślenia na polach w strukturze wskazują, że są one prywatne i mogą ulec zmianie. Nie wyobrażam sobie, że wiele zmian zachodzi w niskopoziomowych funkcjach NSDecimal, ale denerwuję się, że w pewnym momencie coś się załamie.
Biorąc pod uwagę, że inicjowanie NSDecimal z liczby zmiennoprzecinkowej najlepiej zrobić w sposób, który opisujesz. Należy jednak pamiętać, że za każdym razem, gdy używasz wartości zmiennoprzecinkowej, tracisz uzyskaną dokładność za pomocą wartości NSDecimal i będziesz narażać się na błędy zmiennoprzecinkowe.
Zawsze pracuję tylko z NSDecimals w moich precyzyjnych obliczeniach, a także biorę i eksportuję NSStrings do wymiany tych wartości ze światem zewnętrznym. Aby utworzyć NSDecimal oparciu o NSString, można stosować metodę bierzemy w Core Plot framework:
NSDecimal CPDecimalFromString(NSString *stringRepresentation)
{
NSDecimal result;
NSScanner *theScanner = [[NSScanner alloc] initWithString:stringRepresentation];
[theScanner scanDecimal:&result];
[theScanner release];
return result;
}
Korzystanie NSScanner zamiast NSDecimalNumber -initWithString:locale:
jest o 90% szybszy w moich benchmarków.
To naprawdę wydaje się 'NSDecimal' został zaprojektowany dla rzeczy o określonych zakresach precyzyjnych gdzie dokładny dokładność jest ważne, jak waluta, której zazwyczaj nie chcą konwertować ** ani do, ani z ** a 'float' lub' double' z powodu ryzyka utraty precyzji. Czy mógłbyś powiedzieć nam więcej o twoim przypadku użycia? –