Обновление: Это довольно старый ответ, но похоже, что люди все еще находят его.Я хочу обновить это для корректности - первоначально я ответил на вопрос, поскольку я просто продемонстрировал, как можно извлечь конкретные десятичные знаки из double
, но я не защищаю это как способ представления информации о валюте.
Никогда использовать числа с плавающей запятой для представления информации о валюте.Как только вы начинаете работать с десятичными числами (как если бы вы использовали доллары с центами), вы вводите в код возможные ошибки с плавающей запятой.Компьютер не может точно представить все десятичные значения (1/100.0
, например, 1 цент, представлен на моем компьютере как 0.01000000000000000020816681711721685132943093776702880859375
).В зависимости от того, какую валюту вы планируете представлять, всегда правильнее хранить количество в пересчете на его базовую сумму (в данном случае в центах).
Если вы храните свои долларовые значения в виде целых центов,Вы никогда не столкнетесь с ошибками с плавающей запятой для большинства операций, и банально легко конвертировать центы в доллары для форматирования.Если вам нужно, например, применить налог или умножить значение ваших центов на double
, сделайте это, чтобы получить значение double
, примените округление банкира для округления до ближайшего цента и обратного преобразованияв целое число.
Это становится сложнее, чем если вы пытаетесь поддерживать несколько разных валют, но есть способы справиться с этим.
tl; dr Не используйте числа с плавающей точкой для обозначения валюты, и вы будете намного счастливее и правильнее.NSDecimalNumber
может точно (и точно) представлять десятичные значения, но как только вы преобразуете в double
/ float
, вы рискуете ввести ошибки с плавающей запятой.
Это можно сделать относительно легко:
- Получите значение
double
десятичного числа (это будет работать, если число не слишком велико, чтобы хранить его в двойном числе). - В отдельной переменной приведите
double
к целому числу. - Умножьте оба числа на 100, чтобы учесть потерю точности (по сути, конвертируйте в центы), и вычтите доллары из оригинала, чтобы получить количество центов..
- Возврат в строку.
(Это общая формула для работы со всеми десятичными числами - для работы с NSDecimalNumber
требуется всего лишь немного клея для получения кодана работу).
На практике это будет выглядеть так (в категории NSDecimalNumber
):
- (NSString *)cents {
double value = [self doubleValue];
unsigned dollars = (unsigned)value;
unsigned cents = (value * 100) - (dollars * 100);
return [NSString stringWithFormat:@"%02u", cents];
}