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