-4

可能重复:
浮点比较

嗯,这是一个奇怪的。通常以下if( 4.0 == 4.0 ){return true}将始终返回true。在我拥有的一个简单的 opengl 3d '射手'程序中,当我尝试添加'跳跃'效果时,情况并非如此。

这个想法相当简单,我有一个三角形地带的地形,当“角色”移动/行走时,你会沿着二维高度阵列移动,因此你会在山丘/低谷的不同高度上下行走。

drawScene()函数之外(或者如果你知道 opengl,the glutDisplayFunc()),我有一个update()函数可以在角色“跳跃”时上下提升角色,这被称为 in drawScene()。换句话说,尽我所能解释的高级,跳跃算法如下:

参数:

double currentJumpingHeight
double maximumJumpingHeight = 4.0
double ypos;
const double jumpingIncrement = 0.1; //THE PROBLEM!!!! HAS TO BE A MULTIPLE OF 0.5!!
bool isJumping = false;
bool ascending = true;

算法:

(when space is pressed) isJumping = true.

if ascending = true and isJumping = true, 
      currentJumpHeight += jumpingIncrement (and the same for ypos)

if currentJumpingHeight == maximumJumpingHeight, //THE PROBLEM
     ascending = false
     (we decrement currentJumpingHeight and start to fall until we hit the ground.)

它非常简单,但只有当 jumpingIncrement 是0.5!!

如果jumpingIncrement是,比如说,,0.1那么currentJumpingHeight永远不会等于maximumJumpingHeight。角色像火箭一样起飞,永远不会回到地面。即使两个变量打印到标准输出并且相同,条件也永远不会为真。这是我想解决的问题,很荒谬。

我不想要关于跳跃算法的任何反馈——请只看上面的段落。

请帮忙。

4

2 回答 2

5

这只是一个典型的浮点精度问题。特别是0.1不能使用二进制浮点数精确表示。另一方面,像 0.5 和 0.25 这样的数字可以精确表示,因此可能会起作用。我相信即使在这种情况下,编译器仍然可以让它不起作用。

在您的情况下,解决方案正在使用>=

if ascending && (currentJumpingHeight >= maximumJumpingHeight)
     ascending = false
     currentJumpingHeight = maximumJumpingHeight

您也可以使用 epsilon 比较,但我尽可能避免使用它们。在您的情况下,简单>=似乎比 epsilon 平等更清洁。

于 2012-06-16T16:33:20.773 回答
3

正如人们所说,这是一个典型的浮点精度问题。看看这个 基本上,同样的方式,你不能用有限的数字 1/3 以 10 为基数进行编码

1/3 = 0.3333333333.....

你不能在 base 2 中做 1/10。它将是

0.1 = 0x0.0001100110011001100110011001100110011001100110011...

您永远不应该比较浮点数,但要检查差异是否小于一个值,例如

if (fabs(a-b) < 1e-6)

代替

if(a==b)

当然,在您的情况下,只需使用'> ='。

它适用于您的 0.5 增量,因为 0.5 是二进制的 1/2 或 0.1,因此编码正确。这适用于 2 的任何幂,即 0.5 或 0.125,但绝不适用于 0.1。

于 2012-06-16T16:45:59.340 回答