今天,沉浸在神犇博客中的我,看到z姐姐在群里发的一个还很有意思的问题:不用库函数怎么开根,这题好整啊,顿时感觉到可以从大佬的博客中解脱一会了(逃
这个问题是很标准的牛顿迭代问题,第一次研究它的时候应该是在大一上学期吧,当时我第一次对一些库函数的实现产生了好奇(这种好奇止于禽兽的sqrt源码),这种问题可以全部归结于解方程的问题,而解方程的问题用牛顿迭代解决则是一种好方法:
要解决这类问题,只要记住一个公式:
就完了。
推导过程 请联系泰勒获取泰勒级数等相关知识(跑
感谢当年还算勤奋的自己。
#include <bits/stdc++.h>
using namespace std;
double ABS(double a) {
return a<0?-a:a;
}
int main(int argc, char const *argv[])
{
double a;
while(cin >> a) {
if(a<=0) {
puts("no");
}
else {
double x0 = 1.5;
double x1 = 1.0;
while(ABS(x1-x0)>FLT_MIN) {
x0 = x1;
x1 = (x0+a/x0)*0.5;
}
if(x1*x1==a) {
puts("yes");
}
else {
puts("no");
}
}
}
return 0;
}
对了 网上还流传着这样一段禽兽代码:float InvSqrt(float x)
{
float xhalf = 0.5f * x;
int i = *(int*)&x;
i = 0x5f375a86 - (i>>1);
x = *(float*)&i;
x = x*(1.5f-xhalf*x*x);
x = x*(1.5f-xhalf*x*x);
x = x*(1.5f-xhalf*x*x);
return 1/x;
}
据说是雷神之锤3的源代码