C#浮动bug? 0.1 - 0.1 = 1.490116E-08

时间:2009-01-25 23:01:25

标签: c# floating-point

发生了什么事?!减法工作正常,直到达到0.1 - 0.1。我使用nonoba.com API在visual c#2008中。

Console.WriteLine("hit! " + Users[targetNum].character.health + " : " + player.character.profile.attackPower);

Users[targetNum].character.health -= player.character.profile.attackPower;

Console.WriteLine("health! " + Users[targetNum].character.health);

输出:

hit! 0.1 : 0.1
health! 1.490116E-08

全部谢谢 - 我可能会使用十进制类型,因为我通常会添加/减去漂亮的“圆形”数字。现在我将继续:

if (Users[targetNum].character.health <= 0.00001)

顺便说一下,我知道这不会成为c#中的“bug” - 我认为这可能是因为我的代码中存在错误或者缺乏理解,这就是它。

阅读完所有推荐的阅读后,我将得出结论,我的愚蠢是由于通常使用ActionScript Number类型,它可能有一个十进制而不是二进制浮点 - 无论如何,它永远不会给出这个输出。 / p>

5 个答案:

答案 0 :(得分:17)

对于浮点数学来说,这似乎很正常...你总是要检查一个小的delta来解释难以察觉的舍入差异。根据具体情况,decimal可能就是您想要的。

基本上,除非你能确定它在两种情况下完全相同的0.1(即没有对它们做任何事情),否则你不可能得到零;一般来说,你会得到几乎为零的东西。使用decimal,您通常可以直观地获得更多内容。

另见Jon Skeet的页面:

答案 1 :(得分:12)

您显然需要阅读"What Every Computer Scientist Should Know About Floating Point Numbers"

我没有想到我在这种情况下发现了一个错误,我通常认为我的一个假设需要先检查。

答案 2 :(得分:1)

如果您总是添加和减去“精简”数字,即十分之一或百分之一,那么您可以用整数十分之一的单位跟踪您的命中和健康值。一个类比是一个金融程序,它以整数美分跟踪货币,而不是浮点美元。使用整数避免了浮点数学的所有问题。

答案 3 :(得分:0)

浮点数学总是近似的,在任何语言中,因为这就是CPU的工作方式。如果你关心答案的绝对精确度 - 例如,因为你正在处理金钱 - 那么你就不应该使用浮点数。

答案 4 :(得分:0)

略微偏离主题,但这是一篇有趣的读物,描述了即使cos(x) != cos(y) x == y {{1}}为什么{{1}}也可以为真:

http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18