关于在计算机上处理媒介的问题,我们应该了解以下内容。 在比较浮点数时,由于浮点不精确,必须小心。 我们预计相同的两个浮点数可能略有不同。 例如,在数学上,我们希望归一化矢量的长度为1,但在计算机程序中,长度将只是大约1.此外,对于任何实数p,数学上1p = 1,但是当我们只 有1的数值近似,我们看到提升到p次幂的近似值增加了误差; 因此,数值误差也会累积。 以下简短的程序说明了这些想法:
#include <windows.h> // for XMVerifyCPUSupport #include <DirectXMath.h> #include <DirectXPackedVector.h> #include <iostream> using namespace std; using namespace DirectX; using namespace DirectX::PackedVector;
int main() { cout.precision(8);
// Check support for SSE2 (Pentium4, AMD K8, and above). if (!XMVerifyCPUSupport()) { cout << "directx math not supported" << endl; return 0; }
XMVECTOR u = XMVectorSet(1.0f, 1.0f, 1.0f, 0.0f); XMVECTOR n = XMVector3Normalize(u);
float LU = XMVectorGetX(XMVector3Length(n));
// Mathematically, the length should be 1. Is it numerically? cout << LU << endl; if (LU == 1.0f) cout << "Length 1" << endl; else cout << "Length not 1" << endl;
// Raising 1 to any power should still be 1. Is it? float powLU = powf(LU, 1.0e6f); cout << "LU^(10^6) = " << powLU << endl;
} 
为了弥补浮点不精确性,我们测试两个浮点数是否近似相等。 我们通过定义一个Epsilon常量来做到这一点,这是一个非常小的值,我们用它作为“缓冲区”。如果它们的距离小于Epsilon,我们说两个值大致相等。 换句话说,Epsilon为我们提供了浮点不精确度的一些容差。 以下函数说明Epsilon如何用于测试两个浮点值是否相等:
const float Epsilon = 0.001f; bool Equals(float lhs, float rhs) { // Is the distance between lhs and rhs less thanEPSILON? return fabs(lhs - rhs) < Epsilon ? true : false;
} 当测试具有允许公差Epsilon参数的矢量的相等性时,DirectX Math库提供了XMVector3NearEqual函数:
// Returns // abs(U.x – V.x) <= Epsilon.x && // abs(U.y – V.y) <= Epsilon.y && // abs(U.z – V.z) <= Epsilon.z XMFINLINE bool XM_CALLCONV XMVector3NearEqual( FXMVECTOR U, FXMVECTOR V, FXMVECTOR Epsilon);
|