以下是代码:
#define MIN_RESOLUTION ( 0.0000001)
double yMax, yMin;
// calculate yMax, yMin
//....
if( fabs( yMax - yMin) > MIN_RESOLUTION)
{
scaleMin = yMin;
scaleMax = yMax;
}
else
{
// following two lines are executing
scaleMin = yMin - 1.0;
scaleMax = yMax + 1.0;
// could still be the same...
if(scaleMin == scaleMax)
{
if(scaleMax > 0) // decrease min
scaleMin = 0;
else // increase max
scaleMax = 0;
}
}
assert(scaleMin != scaleMax);
在我的示例yMin == yMax == 1.6170737412027187 e17
中。因此,第14行和第15行始终执行:
scaleMin = yMin - 1.0;
scaleMax = yMax + 1.0;
据我所知,double的精度有限(15位),加/减1的运算对于这么大的数字没有多大意义。但我希望“==”操作总是给出'true'然后作为结果。事实并非如此。
有时会发生第18行中的两个双精度不相等( scaleMin == scaleMax ),并且几行之后它们相等(即触发第27行中的断言)。这些数字总是一样的(1.6170737412027187 e17)
我也尝试用这个替换第(27)行:
if (scaleMin == scaleMax)
{
assert(false);
}
行为仍然相同。有什么想法吗?
答案 0 :(得分:2)
请记住,保存在寄存器中时浮点值的表示不一定与内存中的浮点值相同。
例如,在x86上,默认情况下(尽管你可以change this),FPU寄存器对80位尾数的值执行计算,当值作为IEEE存储在内存中时会被截断为53位双打。
因此,在优化代码中,由于可能无关的代码需要寄存器或由于您无法控制的其他原因,因此它们会被刷新到内存中,因此在C行之间看起来会略微发生变化。 / p>
因此,您通常不能将==用于示例代码等目的。
答案 1 :(得分:-2)
你不能对浮点数和双打数使用精确的等式检查。
即使在您执行以下操作的情况下:
float a = calculate_sin_in_0();
float b = calculate_cos_in_pi_2();
由于机器的工作方式,a和b的值可能略有不同
要正确执行此类检查,您必须将一些小值视为无关紧要:
const float eps = 0.00001;
if (abs(a - b) < eps) { // consider a == b
// ...
}