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

这是怎么回事?! 减法工作正常,直到达到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类型,它可能有一个十进制而不是二进制浮点 – 无论如何,它永远不会给出这个输出。

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

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

另见Jon Skeet的页面:

  • 二进制浮点
  • 十进制浮点

你显然需要阅读“每个计算机科学家应该知道的浮点数” 。

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

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

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

这是一个有趣的读物,描述了为什么即使x == y cos(x) != cos(y)也可以为真:

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