具有浮点值和转换的算术运算的错误结果 - 差异很大,我想这不是不准确值的情况 (429497)?

Wrong results for aritmetic operations with float values & casting - big diffrence, I guess it's not a case of inncacurate values (429497)?

我有一些代码:

float distance = pos + (screenSpeed * (float)(lastUpdateTimeMS - actualTimeMS));

这一行应该计算角色移动的距离(位置增量,从上次检查到实际时间)。但我发现它给出了荒谬的结果,例如对于:

screenSpeed = 0.0001f;
lastUpdateTimeMS = 106;
actualTimeMS = 106;

我得到 429497 并且公式的以下部分给出了我:

(float)(lastUpdateTimeMS - actualTimeMS) = 4.29497e+009
(screenSpeed * (float)(lastUpdateTimeMS - actualTimeMS)) = 429497

我得到了其他参数的魔法 429497(这不是 float/int 范围的结束或我熟悉的任何东西)(screenSpeed 总是 0.0001flastUpdateTimeMSactualTimeMS 不同 - 有时它们相等,有时不相等)。

lastUpdateTimeMSactualTimeMS 都是 unsigned 类型 (int)。

我知道浮点数有一些不准确,但是相差这么大我不明白。

我在 x64 机器上工作,使用 Visual Studio C++ 2013(无论如何我都是为 x32 构建的),我的项目包括一些库(也许有一些我应该注意的构建选项,或者在设置时.lib 和我的代码不同,会出现此类问题)?

I am aware of that floating point numbers have some inaccurate, but with such a big differences I don't understand it.

首先,浮点误差与您操作的值成正比。

其次,您的计算 lastUpdateTimeMS - actualTimeMS 中两个无符号 32 位值的减法可能会溢出,结果接近 232 .然后将该值转换为 float 并乘以 0.0001f,生成 429497.

换句话说,你的问题是 actualTimeMSlastUpdateTimeMS 稍大。另外,如果变量的名称可以信任,减法不应该反过来吗?

And I get that magic 429497 (which is not the float/int range's end or anything familiar to me)

正好是232 * 0.0001.

(i) 你的变量似乎弄错了:当然应该是 actualTimeMS - lastUpdateTimeMS?

(ii) unsigned - unsignedunsigned,这是您不想要的。而不是强制转换为 float,这是自动完成的(实际上是 double),您应该强制转换为 int 以使其签名。

(iii) 您的诊断有误。 106U - 106U 是零,所以 screenSpeed * (float)(lastUpdateTimeMS - actualTimeMS) 也是零。也许这些变量正在另一个线程中更新(在这种情况下,您需要解决一整套新问题)?也许问题是 pos 变量?