目标C浮点数的乘法给出了意想不到的结果

ben*_*igi 5 c floating-point objective-c

我只是在做两个花车的乘法.为什么这些陈述产生不同的结果?我应该使用花车吗?

500,000.00*0.001660 = 830

奇数浮点乘法

小智 5

为什么这些语句会产生不同的结果?

因为浮点算术并不精确,而且显然您没有足够精确地打印乘数(即具有足够数量的十进制数字)。而且它不.00166只是看起来 0.00166圆润的东西。

我什至应该使用浮点数吗?

不。对于金钱,请使用整数并将它们视为定点有理数。(它们仍然不准确,但明显更好且不易出错。)

  • 差异太大,不能“只是”由浮点运算引起。 (2认同)

rob*_*off 3

您没有显示如何初始化periodicInterest,并且大概您认为将其设置为0.00166,但实际上输出中的错误足够大,您一定没有将其显式初始化为periodicInterest = 0.00166。它必须更接近,并且和0.00165975之间的差异绝对足够大,而不仅仅是单个浮点舍入误差。0.001660.00165975

\n\n

假设您正在处理货币数量,您应该使用NSDecimalNumberNSDecimal

\n\n

使用的一个不明显的好处NSDecimalNumber是它可以与 一起使用NSNumberFormatter,因此您可以让 Apple 负责为各种外国语言环境设置货币格式。

\n\n

更新

\n\n

回应评论:

\n\n
    \n
  • \xe2\x80\x9cperiodicInterest显然不是一个货币数量\xe2\x80\x9d\xc2\xa0 并且 \xe2\x80\x9c 十进制除以 12 时并不比二进制更容易出错 \xe2\x80\x9d - 对于不精确数量,我可以想到两个问题:

    \n\n
      \n
    • 一个问题是使用足够的精度来提供准确的结果。 NSDecimalNumber是一个浮点数,精度为 38 位,指数范围为 -128\xe2\x80\xa6127。这是 IEEE“double” 可以存储的十进制位数的两倍多。指数范围小于 a 的指数范围double,但这在金融计算中不太重要。所以s 绝对可以比s 或sNSDecimalNumber产生更小的误差,尽管它们都不能准确存储 1/12。floatdouble

    • \n
    • 另一个问题是匹配其他系统(例如您的银行、经纪人或纽约证券交易所)计算的结果。在这种情况下,您需要弄清楚其他系统如何存储数字并使用它们进行计算。如果其他系统使用十进制格式(这可能在金融领域),那么NSDecimalNumber可能会很有用。

    • \n
  • \n
  • \xe2\x80\x9c使用基本类型进行浮点运算,特别是实时进行数千次浮点运算,不是会更有效吗。\xe2\x80\x9d 对基本类型的算术比对NSDecimalNumbers 的算术快得多。我没有测量过,但 100 倍不会让我感到惊讶。

    \n\n

    您必须在您的要求之间取得平衡。如果小数精度至关重要(财务编程中经常如此),则必须牺牲性能来换取精度。如果小数精度不是那么重要,您可以仔细考虑使用原始类型,但您应该意识到您所牺牲的精度。即使如此,a 的大小float仍然很小(通常只有 7 位有效小数位),您可能应该使用double(至少 15 位,通常是 16 位有效小数位)。

    \n\n

    如果您需要以真正的十进制精度每秒执行数百万次算术运算,如果您是 IEEE 754 专家,能够分析您的代码以找出引入错误的位置以及如何消除错误,那么您也许可以使用doubles 来完成此操作。很少有人具备这种水平的专业知识。(我不这么认为。)您还必须了解编译器如何将 Objective-C 代码转换为机器指令。

    \n\n

    无论如何,也许您只是编写一个休闲应用程序来计算净现值或未来价值的粗略估计。在这种情况下,使用double可能就足够了,但是使用NSDecimalNumber也可能足够快。如果不了解您正在编写的应用程序的更多信息,我无法为您提供更具体的建议。

  • \n
\n