(数论七)关于sqrt、pow与log的巧用

一. 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在二进制下一共多少位

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

你可能感兴趣的:((数论七)关于sqrt、pow与log的巧用)