К сожалению, 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 в своих высокоточных вычислениях и беру и экспортирую NSStrings для обмена этими значениями с внешним миром. Чтобы создать NSDecimal на основе NSString, вы можете использовать подход, который мы используем в Core Plot framework :
NSDecimal CPDecimalFromString(NSString *stringRepresentation)
{
NSDecimal result;
NSScanner *theScanner = [[NSScanner alloc] initWithString:stringRepresentation];
[theScanner scanDecimal:&result];
[theScanner release];
return result;
}
Использование NSScanner вместо NSDecimalNumber -initWithString:locale:
примерно на 90% быстрее в моих тестах.