iPhone与浮点数学

iPhone与浮点数学,iphone,floating-point,Iphone,Floating Point,我有以下代码: float totalSpent; int intBudget; float moneyLeft; totalSpent += Amount; moneyLeft = intBudget - totalSpent; 花销; 国际预算; 把钱存起来; 总花费+=金额; moneyLeft=intBudget-总花费; 这是调试器中的外观: 为什么上面代码计算的moneyLeft与调试器计算的表达式.02不同 表达式窗口是正确的,但上面的代码生成了错误的by.02

我有以下代码:

float totalSpent; int intBudget; float moneyLeft; totalSpent += Amount; moneyLeft = intBudget - totalSpent; 花销; 国际预算; 把钱存起来; 总花费+=金额; moneyLeft=intBudget-总花费; 这是调试器中的外观:

为什么上面代码计算的moneyLeft与调试器计算的表达式.02不同

表达式窗口是正确的,但上面的代码生成了错误的by.02结果。它只发生在非常大的数字上(但远低于int限制)


多谢了

使用货币类型的计算,浮点运算总是会产生奇怪的结果

黄金法则是,浮点数适用于测量升、码、光年、蒲式耳等,但不适用于像这样计算的东西 羊、豆、钮扣等

大多数货币计算都是计算便士,所以使用整数数学 你不会得到奇怪的结果。或者使用固定的十进制算术 图书馆(这在iPhone上可能是多余的)或储存你的数量
作为整数的美分,仅在显示时转换为美元和美分。

浮点型计算总是会产生奇怪的结果

黄金法则是,浮点数适用于测量升、码、光年、蒲式耳等,但不适用于像这样计算的东西 羊、豆、钮扣等

大多数货币计算都是计算便士,所以使用整数数学 你不会得到奇怪的结果。或者使用固定的十进制算术 图书馆(这在iPhone上可能是多余的)或储存你的数量
作为整数的美分,仅在显示时转换为美元和美分。

单个精度
浮点值
具有23位精度。这意味着每次计算都四舍五入到23位二进制数字。这意味着,如果您有一个计算,比如说,将一个非常小的数字添加到一个非常大的数字,舍入可能会导致奇怪的结果

想象一下,你在用科学符号十进制手工计算数学,规则是你可能只有四个有效数字。比方说,我要求你们用科学记数法写十二,四个有效数字。回忆初中,你写道:

1.200×101

现在我说计算12的平方,然后加0.5。这很容易:

1.440×102+0.005×102=1.445×102

十二次方加0.75怎么样:

1.728×103+0.00075×103=1.72875×103

但请记住,我只给了你四个有效数字的空间,所以你必须四舍五入;然后我们得到:

1.728×103+7.5×10-1=1.729×103

看到了吗?缺乏精确性会使计算结果出人意料

在您的示例中,您在一个计算中得到999999,您试图精确到0.01。log2(999999)=19.93和log2(0.01)=-6.64。差异大于23;因此,您需要23个以上的二进制数字才能准确地执行此计算


因为浮点数学本质上是精确的,所以它通常是货币计算的一个坏选择,在货币计算中必须精确到最后一美分。但是你真的关心你申请表中的零头吗?如果不是,那么为什么不完全取消小数点,只将美分(而不是美元)存储在64位整数中呢?264¢超过了整个地球的GDP。

单个精度
浮点值
有23位精度。这意味着每次计算都四舍五入到23位二进制数字。这意味着,如果您有一个计算,比如说,将一个非常小的数字添加到一个非常大的数字,舍入可能会导致奇怪的结果

想象一下,你在用科学符号十进制手工计算数学,规则是你可能只有四个有效数字。比方说,我要求你们用科学记数法写十二,四个有效数字。回忆初中,你写道:

1.200×101

现在我说计算12的平方,然后加0.5。这很容易:

1.440×102+0.005×102=1.445×102

十二次方加0.75怎么样:

1.728×103+0.00075×103=1.72875×103

但请记住,我只给了你四个有效数字的空间,所以你必须四舍五入;然后我们得到:

1.728×103+7.5×10-1=1.729×103

看到了吗?缺乏精确性会使计算结果出人意料

在您的示例中,您在一个计算中得到999999,您试图精确到0.01。log2(999999)=19.93和log2(0.01)=-6.64。差异大于23;因此,您需要23个以上的二进制数字才能准确地执行此计算


因为浮点数学本质上是精确的,所以它通常是货币计算的一个坏选择,在货币计算中必须精确到最后一美分。但是你真的关心你申请表中的零头吗?如果不是,那么为什么不完全取消小数点,只将美分(而不是美元)存储在64位整数中呢?264美分超过了整个地球的GDP。

非常好的解释,谢谢!我刚刚重新编写了整个应用程序(谢天谢地,所有的计算都在一个类中)来使用NSDecimalNumber,它开始完美地工作了非常好的解释,谢谢!我刚刚重新编写了整个应用程序(谢天谢地,所有的计算都在一个类中),以使用NSDecimalNumber,它开始完美地工作。谢谢你,詹姆斯。见上面的评论。由于我从未编写过金融类应用程序,所以我从未想到float是一种错误的类型谢谢你,詹姆斯。见上面的评论。由于我从未编写过金融类应用程序,所以我从未想到float是一种错误的类型