算术平方根解法

第一种方法,使用二分法。在一个区间内每次拿中间数的平方来试,如果大了就左移中间数,如果小了就右移。当结果逼近真实值的时候取精度最高的结果。

//二分法求平方根,首尾两端不断逼近 
float Sqrt(float m){
	const float eps = 1e-11;
	//eps用于控制结果的精度 
	if(m<0){
		cerr<<"无法求根"<<endl;
		return -1;
	}
	float mid,low,up,last;
	low = 0,up = m;
	mid = (low + up)/2;
	do{
		if(mid * mid > m)
			up = mid;
		else
			low = mid;
		last = mid;
		mid = (low + up)/2;			
	}while(fabs(last - mid) > eps); 
	//不能使用abs,会提示函数有歧义 ,fabs可以直接传float参数 
	return mid;	
}

第二种方法,牛顿迭代法。↓↓↓↓↓↓↓↓以下描述取自百度百科

设r是
的根,选取
作为r的初始近似值,过点
曲线
的切线L,L的方程为
,求出L与x轴交点的横坐标
,称x 1为r的一次近似值。过点
做曲线
的切线,并求该切线与x轴交点的横坐标
,称
为r的二次近似值。重复以上过程,得r的近似值序列,其中,
称为r的
次近似值,上式称为牛顿 迭代公式。
用牛顿迭代法解非线性方程,是把非线性方程
线性化的一种近似方法。把
在点
的某邻域内展开成 泰勒级数
,取其线性部分(即泰勒展开的前两项),并令其等于0,即
,以此作为非线性方程
的近似方程,若
,则其解为
, 这样,得到牛顿迭代法的一个迭代关系式:

简单来说就是,如要求A的算术平方根,先假设一个值x,然后不断求(x+a/x)/2=x,不断迭代。
float SqrtByNt(float m){
	const float eps = 1e-11;
	float x = m; 
	float last;//用于记录上一次迭代的值 
	do{
		last = x;
		x=(x+m/x)/2;		
	}while(fabs(x-last)>eps);
	return x;
} 

接下来是卡马克的神奇平方根算法,其实也是用了牛顿迭代法,但他设置了一个神奇的常数0x5f3759df来计算那个猜测值。
float InvSqrt (float x) {
	float xhalf = 0.5f*x;
	int i = *(int*)&x;
	i = 0x5f3759df - (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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值