我正在为我的应用程序开发一个单元测试,但是我遇到了一个我不明白的奇怪问题。
代码是:
double res = BytesTool::convertSize(1, BytesTool::Byte, BytesTool::KiloByte);
double tmp = pow((double)1000, -1);
QVERIFY(res == tmp);
我正在使用gcc(主机64位)从Linux机器(主机64位)编译Linux 64位,并使用Linux的mingw32编译器对Windows 32位进行交叉编译。
该程序在调试和发布模式下使用Linux编译正常工作(断言成功)。 对于Windows版本,它在调试版本中工作正常,但不适用于发行版本;断言失败了。
奇怪的是,如果我插入一个跟踪,测试在Windows中可以运行:
double res = BytesTool::convertSize(1, BytesTool::Byte, BytesTool::KiloByte);
printf("test");
double tmp = pow((double)1000, -1);
QVERIFY(res == tmp); // Is TRUE when printf("test") is present, FALSE otherwise
我迷路了,我真的不明白发生了什么。为什么printf
能够使其发挥作用?
感谢您的帮助。
答案 0 :(得分:6)
printf将使其工作,因为浮点数将从内部FPU 80位表示(假设x86“旧式”数学运算)转换为保存在double中的64位。
这样做的原因是当你调用另一个函数时,寄存器值必须被移动到堆栈(再次,假设x86旧式FPU调用约定),这将导致它被四舍五入到64位精度。 / p>
您的其他编译很可能有效,因为它们使用SSE2 + math,它具有本机64位浮点类型。
==
测试浮点数相同,这对于浮点数几乎不是正确的。
在这种情况下,它不是因为内部CPU表示与存储在double中的表示不同。
比较浮点数时,请务必检查它们是否彼此足够接近而不是相等。
#include <math.h>
QVERIFY( fabs(res-tmp) < DBL_EPSILON )
答案 1 :(得分:-1)
它将会消失一点点。 Double的工作原理与浮点相同,这很好地解释了https://www.youtube.com/watch?v=PZRI1IfStY0