objective-c - NSDecimalNumber 的小数部分

标签 objective-c xcode nsdecimalnumber mantissa

我正在使用 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,您就会面临以下风险引入浮点错误。


这可以相对容易地完成:

  1. 获取十进制数的 double 值(假设数字不是太大而无法存储在 double 中,这将起作用)。
  2. 在一个单独的变量中,将 double 转换为整数。
  3. 将这两个数字乘以 100 以弥补精度损失(本质上是转换为美分),然后从原始数字中减去美元以获得美分数。
  4. 以字符串形式返回。

(这是处理所有十进制数的通用公式 - 使用 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/

相关文章:

ios - 将 Xcode 5 应用程序上传到 iOS 8 手机

objective-c - 如何避免xcode运行app的情况?

SwiftUI - 将数据传递到不同的 View

ios - NSDecimalNumberOverflowException - 问题

php - iOS 使用 http post/get 从 tableView 远程删除行

objective-c - 如何隐藏 iOS 模拟器?

ios - 如何在 LLDB 中调试成员变量(即 Array、Dictionary)?

ios - 如何从 NSDecimal 获取 NSDecimalNumber 的值?

objective-c - NSNumberFormatter,NSDecimalNumber和科学计数法

objective-c - 不能从捕获上下文的局部函数形成 C 函数指针