比较IEEE浮点数和双精度数是否相等Comparing IEEE floats and doubles for equality

15 个回复15

===============>>#1 票数：7 已采纳

``````bool is_nan(float f)
{
return (*reinterpret_cast<unsigned __int32*>(&f) & 0x7f800000) == 0x7f800000 && (*reinterpret_cast<unsigned __int32*>(&f) & 0x007fffff) != 0;
}

bool is_finite(float f)
{
return (*reinterpret_cast<unsigned __int32*>(&f) & 0x7f800000) != 0x7f800000;
}

// if this symbol is defined, NaNs are never equal to anything (as is normal in IEEE floating point)
// if this symbol is not defined, NaNs are hugely different from regular numbers, but might be equal to each other
#define UNEQUAL_NANS 1
// if this symbol is defined, infinites are never equal to finite numbers (as they're unimaginably greater)
// if this symbol is not defined, infinities are 1 ULP away from +/- FLT_MAX
#define INFINITE_INFINITIES 1

// test whether two IEEE floats are within a specified number of representable values of each other
// This depends on the fact that IEEE floats are properly ordered when treated as signed magnitude integers
bool equal_float(float lhs, float rhs, unsigned __int32 max_ulp_difference)
{
#ifdef UNEQUAL_NANS
if(is_nan(lhs) || is_nan(rhs))
{
return false;
}
#endif
#ifdef INFINITE_INFINITIES
if((is_finite(lhs) && !is_finite(rhs)) || (!is_finite(lhs) && is_finite(rhs)))
{
return false;
}
#endif
signed __int32 left(*reinterpret_cast<signed __int32*>(&lhs));
// transform signed magnitude ints into 2s complement signed ints
if(left < 0)
{
left = 0x80000000 - left;
}
signed __int32 right(*reinterpret_cast<signed __int32*>(&rhs));
// transform signed magnitude ints into 2s complement signed ints
if(right < 0)
{
right = 0x80000000 - right;
}
if(static_cast<unsigned __int32>(std::abs(left - right)) <= max_ulp_difference)
{
return true;
}
return false;
}
``````

===============>>#2 票数：3

``````bool is_equals(float A, float B,
float maxRelativeError, float maxAbsoluteError)
{

if (fabs(A - B) < maxAbsoluteError)
return true;

float relativeError;
if (fabs(B) > fabs(A))
relativeError = fabs((A - B) / B);
else
relativeError = fabs((A - B) / A);

if (relativeError <= maxRelativeError)
return true;

return false;
}
``````

===============>>#3 票数：1

• y = beta * y + alpha * A * x
• y = beta * y + alpha * A ^ T * x
• y = beta * y + alpha * A ^ H * x

PS：

• 肯定有很多情况下你不想检查“完全相同”。 对于许多人来说，这甚至可能是他们唯一需要处理的案例。 我只想指出的是，还有其他案例。

• 虽然LAPACK是用Fortran编写的，但如果你使用其他编程语言编写数字软件，那么逻辑就是一样的。

===============>>#4 票数：1

@DrPizza：我不是性能大师，但我希望定点操作比浮点运算更快（在大多数情况下）。

3D图形，物理/工程，模拟，气候模拟....

===============>>#5 票数：0

Floats允许我得到数学问题的解决方案，因为值在低端溢出了很多零。 所以你基本上在数字中有一个小数点浮动aronud而没有精度损失（我可以想象浮点数的尾数中允许的值与64位int相比更有限，但是迫切需要th范围！ ）。

===============>>#9 票数：0

ULP是两个浮点数之间“距离”的直接度量。 这意味着它们不需要您想出相对和绝对错误值，也不必确保将这些值“约为正确”。 使用ULP，您可以直接表达您希望数字的接近程度，同样的阈值也适用于小值和大值。

===============>>#13 票数：0

``````#include <iostream>

using namespace std;

int main()
{
float a = 1.0;
float b = 0.0;

for(int i=0;i<10;++i)
{
b+=0.1;
}

if(a != b)
{
cout << "Something is wrong" << endl;
}

return 1;
}
``````

===============>>#14 票数：0

@DrPizza：我不是性能大师，但我希望定点操作比浮点运算更快（在大多数情况下）。

@Craig H：好的。 我打印它完全没问题。 如果a或b存钱，那么它们应该以固定点表示。 我正在努力想到一个真实世界的例子，这种逻辑应该与浮动联合起来​​。 适合花车的东西：

• 权重
• 行列
• 距离

3回复

4回复

4回复

6回复

7回复

3回复

2回复

2回复

10回复

2回复