sqrt函數實現分析

看到一篇博文講述sqrt的實現方法,其中二分法沒有區分區間,當x位於(0,1)和(1, 正無窮) 時初始值設置應該有所區別


const float eps=0.000001;	// eps的值可能影響最後計算精度,甚至導致無限循環
// 二分法,注意區分x的取值區間
float SqrtByBisection(float x)
{
	if(x<0)	// 負數
		return x;
	if(x<=eps)	// 正數0
		return 0.0f;
	if(fabs(x-1)<=eps)	// 正數1
		return 1.0f;
	float left, right;
	float mid;
	if(x>eps&&x<1.0f-eps)	// (0,1)區間
	{
		left=x;
		right=1.0f;
	}	
	else
	{
		left=1.0f;
		right=x;
	}		
	while(right-left>eps)	// (1,)區間
	{
		mid=(left+right)/2;
		if(mid*mid>x+eps)
			right=mid;
		else if(mid*mid<x-eps)
			left=mid;
		else
			return mid;
	}	
	return mid;
}

上述方法雖然考慮了區間,但是驗證時還是出現細節問題,如sqrt(0.25)=0.499999等

與二分法相比,牛頓迭代法速度更快,計算也更準確


// 牛頓迭代法
float SqrtByNewton(float x)
{
	float val=x;
	float last;
	while(fabs(val-last)>eps)
	{
		last=val;
		val=(val+x/val)/2;
	}
	return val;
}

更快的方法,原來用在一款遊戲中,參加:http://zh.wikipedia.org/wiki/%E5%B9%B3%E6%96%B9%E6%A0%B9%E5%80%92%E6%95%B0%E9%80%9F%E7%AE%97%E6%B3%95


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章