警示后人&一种不一样的解题思路
  • 板块B3627 立方根
  • 楼主__Luna__
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/7/26 16:31
  • 上次更新2025/7/26 22:06:04
查看原帖
警示后人&一种不一样的解题思路
901195
__Luna__楼主2025/7/26 16:31

首先警示后人,如果你用牛顿迭代,千万别写出类似const double twothird = 0.66667;这样的唐氏东西,这个玩意精度差一点会严重影响最终结果导致会炸掉(别问我怎么知道的)。

然后是一种不一样的解题思路。《雷神之锤Ⅲ》里有一种著名的平方反根算法,也就是这个:

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;
}

我们其实可以有一种类似的算法求立方根:

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) 时间复杂度——虽然结果是近似的就是了……

2025/7/26 16:31
加载中...