将两个从无符号整数转换而来的浮点数相除可能会产生负浮点数结果?

3
unsigned int deltaTime = now() - last();
unsigned int freq = getFreq();
float timeOfGap = float(deltaTime) / float(freq);

ASSERT(0.0f <= timeOfGap, "WHAT?");

我的程序结果非常奇怪。我没有捕捉到发生的场景,但是我有一份日志记录显示至少出现了多次。

两个从无符号整数转换而来的浮点数相除可能会导致负浮点数结果吗?


好的,谢谢大家。很高兴看到你们的关注。 让我尝试添加一些描述。这将对您有所帮助。

我正在为一个在线游戏工作,在服务了数亿次游戏后,这种情况很少但频繁地出现。我无法调试或捕捉到确切的错误,但它在数据库错误消息中被记录下来。

如您所注意,timeOfGap应该为NaN,但日志没有精确提示该值。 timeOfGap是按以下方式累积的;

mTotalFrameRateTimeAsASecond += timeOfGap;

这个程序记录了mTotalFrameRateTimeAsASecond,它是一个负值。但除了这个符号是负数外,它是正确的值。这意味着,如果我将最终值除以帧速率,它就能正确指示时间。一个假设的播放时间是500秒,在每秒60帧的情况下,它是-30000。


2
你尝试过打印你的 timeOfGap 吗?也许它是 NAN。 - Mihran Hovsepyan
4个回答

3
也许它不是负数,而是一个NAN0.0f <= NANfalse。如果两个操作数都是零,这种情况可能会发生。

1
好的,你可能是对的。还有一个问题,NaN 可以正确累加吗? - hey
@hey:什么叫正确累加?任何NaN的算术运算结果都是NaN。包括NaN==NaN或者NaN!=NaN的比较结果都为false。 - Juraj Blaho
正如我上面提到的,每次计算时间间隔后,我得到了一个正常大小的数字。但它只是负数。 - hey
@hey:那么代码中可能存在其他错误。如果“0.0f <= timeOfGap”不成立,您应该进行调试或跟踪/打印“float(deltaTime)”和“float(freq)”的值。 - Juraj Blaho

0

这应该可以找到问题:

unsigned int deltaTime = now() - last();
unsigned int freq = getFreq();
float timeOfGap = float(deltaTime) / float(freq);
char s[50] ;
sprintf (s, "WHAT? %u/%u < 0!", deltaTime, freq);

ASSERT(0.0f <= timeOfGap, s);

0

nan 的值将无法成功地与任何内容进行比较。因此,如果您有:

float f = 0.0 / 0.0;

assert(f > 0 || f <= 0);

断言将会失败!


Inf 可以成功比较。 - Juraj Blaho

-1

您可以进行一个简单的测试来验证从无符号整数到浮点数的转换。

试试这个:

unsigned int toto = 0xFFFFFFFF; 
float convertedToto = float(toto);

convertedToto将等于-1,如果转换(无符号整数 -> 浮点数)实际上是(整数 -> 浮点数)。您应该通过适当的转换获得2 * 10e31。


两个错误:(i)在任何系统中,0x80000000都不是-1 - 你的意思是-(2^31)。(ii)2e31表示2 * 10^31,而不是2^31。 - TonyK
抓住它,Rockeye!2*10e31意味着2*10*10^31 - TonyK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接