之所以如此,是因为指数是奇数时,指数的最后一位左移后进入尾数,相当于在尾数部分添加2k-1。也就是说,此时除了泰勒级数误差之外,还有一个代替误差:
相对误差约:
最大约5.62%。最终的误差是这个误差与泰勒级数展开误差的混合。
从上述分析可以看出,相对误差只与尾数构成有关,与取值范围无关,因此下面以[0,1]区间做试验,结果见表13-1。
表13-1 [0,1]平方根值
最大误差约6%左右,对于一般的3D计算而言,这个精度可以满足要求。
平方运算的原理与平方根运算类似,不再赘述。代码如下:
- __declspec( naked ) float fast_x2( float x )
- {
- __asm
- {
- SUB ESP, 4
- MOV EAX, [ESP+8]
- SUB EAX, 0x3F800000
- SAL EAX, 1
- ADD EAX, 0x3F800000
- MOV [ESP], EAX
- FLD DWORD PTR [ESP]
- ADD ESP, 4
- RET
- }
- }
试验结果见表13-2。最大误差有11%(表中没有出现)。
表13-2 [0,1]平方值
另外,平方运算有一个限制,那就是0.0时无法用这种算法,需要剔除。注意,IEEE的0有两种:+0和-0,因此检测代码是:
- if( ( *(unsigned int*)&x == 0 ) ||
- ( *(unsigned int*)&x == 0x80000000 ) )
- return 0.0f;
-
- 不要使用下列代码:
-
- if( x == 0.0f )
- return 0.0f;
这会导致编译器使用浮点指令。
【责任编辑:
董书 TEL:(010)68476606】