我正在使用 NSDecimalNumber 来存储货币值。我正在尝试编写一个名为“cents”的方法,如果数字 < 10,它会将数字的小数部分作为带前导 0 的 NSString 返回。所以基本上
NSDecimalNumber *n = [[NSDecimalNumber alloc] initWithString:@"1234.55"];
NSString *s = [object cents:n];
我正在尝试设计一种方法,它将返回 01、02 等……最多 99 个字符串。我似乎无法弄清楚如何以这种格式将尾数作为字符串返回。我觉得我错过了一个方便的方法,但我再次查看了文档,没有发现任何问题。
最佳答案
更新:这是一个相对较旧的答案,但看起来人们仍在寻找它。我想更新它以确保正确性——我最初回答这个问题只是为了演示如何从 double
中提取特定的小数位,但我不提倡将此作为表示货币的一种方式信息。
切勿使用 float 来表示货币信息。一旦开始处理小数(就像处理美元和美分一样),您就会在代码中引入可能的浮点错误。计算机无法准确表示所有小数值(1/100.0
,例如,1 分,在我的机器上表示为 0.01000000000000000020816681711721685132943093776702880859375
)。根据您计划表示的货币,以基本金额(在本例中为美分)存储数量总是更正确。
如果您以整分的形式存储美元值,则大多数操作都不会遇到浮点错误,并且将美分转换为美元以进行格式化也非常容易。例如,如果您需要征税,或将您的美分值乘以 double
,执行此操作以获得 double
值,请应用 banker's rounding舍入到最接近的分,然后转换回整数。
如果您尝试支持多种不同的货币,事情会变得更加复杂,但有一些方法可以解决这个问题。
tl;dr 不要使用 float 来表示货币,这样您会更快乐、更正确。 NSDecimalNumber
能够精确地(精确地)表示十进制值,但是一旦您转换为 double
/float
,您就会面临以下风险引入浮点错误。
这可以相对容易地完成:
- 获取十进制数的
double
值(假设数字不是太大而无法存储在 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];
}
关于objective-c - NSDecimalNumber 的小数部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5355755/