float sq(float f){ //快速开方
int o=((( ( *( (int*)&f ) )^0x00800000 )>>1)&0xbfffffff)+0x20000000;
if(o&0x00400000>0){
o-=0x00800000;
}
return *((float*)&o);
}
主要看第23位
e=(e^7,e^6,…,e^0)-0x01111111
如果是1:
则最简单,变量右移1位相当于除2,小数部分应该为√(1+a),实际 为(1+a/2),两者只存在于0<=a<1,差别如下
可以看出差别不大;
如果是0:
则在上面的基础上加入一个if语句
if(/**第22位是1**/){
o-=0x00800000;
}
此时小数部分应该为√(2*(a+1)),实际为(1+(1+a)/2),同样0<=a<1,偏差如下图
偏差很小。
待测值 理论 实际
4000.0 63.245 63.25
1000.0 31.623 31.625
256.0 16.0 16.0
100.0 100.0 100.25