社区讨论

警示后人&一种不一样的解题思路

B3627立方根参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mdjzsfhp
此快照首次捕获于
2025/07/26 16:32
7 个月前
此快照最后确认于
2025/11/04 03:41
4 个月前
查看原帖
首先警示后人,如果你用牛顿迭代,千万别写出类似const double twothird = 0.66667;这样的唐氏东西,这个玩意精度差一点会严重影响最终结果导致会炸掉(别问我怎么知道的)。
然后是一种不一样的解题思路。《雷神之锤Ⅲ》里有一种著名的平方反根算法,也就是这个:
CPP
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

	return y;
}
我们其实可以有一种类似的算法求立方根:
CPP
double Q_cbrt(double number)
{
	long long i;
	double x2, y;
	const double twothird = 2.0 / 3;
	x2 = number * 0.5;
	y = number;
	i = * (long long *) &y;   
	i = 3071319837877857280ll + i / 3;     
	y = * (double *) &i;
	y = twothird * (y + x2 / y / y);
	y = twothird * (y + x2 / y / y);
	y = twothird * (y + x2 / y / y);
    y = twothird * (y + x2 / y / y);
	return y;
}
当然这个算法的效率比平方反根是差不少的,因为用了很多除法运算。 但是它依然是高贵的 O(1)O(1) 时间复杂度——虽然结果是近似的就是了……

回复

1 条回复,欢迎继续交流。

正在加载回复...