一. sqrt
大家都知道sqrt(x)是求x的平方根,c中自带的math.h库有关于该函数的使用。这里就不多叙述~
关于求sqrt,这里有一个神人约翰-卡马克,大家可以百度搜索一下这个神人的辉煌事迹(求sqrt的神秘数字),附上它的代码%一下:
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
#ifndef Q3_VM
#ifdef __linux__
assert( !isnan(y) ); // bk010122 - FPE?
#endif
#endif
return y;
}
它的这段代码求sqrt(number)的倒数,速度比math.h库中的(float)(1.0/sqrt(x))快4倍!!!
注释中的what the fuck? 也表明了我们普通人的心情。。。。
话不多说,%%%%%%%%%%%%%%%%%%%%%%%%%%就完了
二.pow
关于pow函数也存在与math.h库中,具体使用也不详细介绍,我们来说一下它的巧用
假如a^b = c,我们已知b和c,如何求a?(其中b <= 200, a <= 1e9, c <=1e100 )
注意!!c的取值范围是1e100!!!
这时候就有一个巧办法了,虽然double精度不足1e100,但我们只需要知道它的前16位即可,因为当b错一位,c的前16位变化很大。所以虽然double只保留了16位,但计算出的c是唯一的。因此:
pow (c, 1 / n)保留0位小数,即为a
三.log
关于log的巧妙用法
第一个:例如给出a, b, c, d,如何比较ab与cd的大小?
我们只需要求p = b✖️log(a); q = d✖️log©
如果p - q的绝对值 <= 1e-6,则两者相等,
如果 p < q ,则a^b < c^d,
否则a^b > c^d
第二个:求一个数x有多少位数:
利用(int)log10(x) + 1可以求得x一共多少位
第三个:求一个数x在二进制下有多少位:
利用(int)log2(x) + 1可以求得x在二进制下一共多少位
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢