看看libm中日志操作的实现,我对一些数字文字有问题。
从here下载代码
代码的一部分如下所示。我想知道0x95f64,0x6147a和0x6b851是什么意思。
if (hx >= 0x7ff00000) return x+x;
k += (hx>>20)-1023;
hx &= 0x000fffff;
i = (hx+0x95f64)&0x100000;
SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
k += (i>>20);
f = x-1.0;
if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
if(f==zero) { if(k==0) return zero; else {dk=(double)k;
return dk*ln2_hi+dk*ln2_lo;}}
R = f*f*(0.5-0.33333333333333333*f);
if(k==0) return f-R; else {dk=(double)k;
return dk*ln2_hi-((R-dk*ln2_lo)-f);}
}
s = f/(2.0+f);
dk = (double)k;
z = s*s;
i = hx-0x6147a;
w = z*z;
j = 0x6b851-hx;
t1= w*(Lg2+w*(Lg4+w*Lg6));
t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
i |= j;
R = t2+t1;更新:我熟悉十六进制表示法。我有兴趣了解代码的内部工作原理与正文标题中描述的算法/方法之间的关系。为什么要使用这些特定值,使用它的目的是什么?
发布于 2019-02-21 01:04:44
sqrt(2)的iee754表示的较高32位字是0x3ff6a09e,其中最高12位(即0x3ff)代表指数,较低20位0x6a09e代表尾数的第一部分。(1<<20)-0x6a09e为0x95f62。在算法部分,我们使用数字0x95f64,我们检查在去除所有2的幂(这使得x在范围1..2)之后,我们是否仍然有x>sqrt(2),在这种情况下,我们将x除以2。但是,我不清楚为什么使用0x95f64而不是0x95f62。
这部分
i = hx-0x6147a;
w = z*z;
j = 0x6b851-hx;
t1= w*(Lg2+w*(Lg4+w*Lg6));
t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
i |= j;
R = t2+t1;
if(i>0) {在源代码中有以下注释
/* In order to guarantee error in log below 1ulp, we compute log
* by
* log(1+f) = f - s*(f - R) (if f is not too large)
* log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)/检查if (( hx - 0x6147a )|( 0x6b851 -hx))>0实际上是检查hx是否在0x6147a和0x6b851范围内。高位字0x3ff6147a的浮点数约为1.38,高位0x3ff6b851的浮点数约为1.42,即略小于sqrt(2),略大于sqrt(2)。还不确定这些数字是否重要。
发布于 2013-09-27 17:51:45
好吧,如果没有人愿意做出完整的回答--我会做出不完整的回答。
我没有太多的时间来弄清楚这些确切的值是从哪里来的,所以我的答案是通用的。这与您在http://en.wikipedia.org/wiki/Fast_inverse_square_root中看到的浮点数的魔力完全相同。例如,hx &= 0x000fffff;只从双精度的高位字中提取尾数(只有20位高位字-更高的位是符号和指数)-这个常量在浮点值的某些部分下执行整数位操作(特别是在尾数上,如我所见)。进行这种计算需要付出相当大的努力,但在像libc这样被广泛使用的库中,即使是很小的性能提升也可以被认为是显著的。
之所以这样做,是因为整数运算比浮点运算快得多。也许在当前的CPU中,浮点型和整型之间的性能差异不是很大(特别是如果你考虑到一些SSE和其他向量指令-尽管不是每个算法都能从SIMD指令中获得性能提升),但它要高得多。因此,有人在简化公式和尽可能多地使用整数而不是浮点数进行计算方面做了令人印象深刻的工作-我假设每个人都复制了这个代码,因为这些常量似乎存在于我能够访问的每个libc中。
我知道这不是你想要的答案-抱歉。您还可以查看brilliant http://graphics.stanford.edu/~seander/bithacks.html
https://stackoverflow.com/questions/19025084
复制相似问题