我听说过这里讨论过的“快速平方根平方根”,我想把它放在我的 Java 程序中(只是为了研究目的,所以忽略任何关于本机库更快的内容)。
我正在查看代码,C 代码直接将 转换float
为int
带有一些 C 指针魔法的。如果您尝试在 Java 中使用强制转换来执行此操作,则它不起作用:java 会截断浮点数(正如您所期望的那样),并且您无法获得原始指针(就像在 C 中那样)。那么你是怎么做到的呢?
我听说过这里讨论过的“快速平方根平方根”,我想把它放在我的 Java 程序中(只是为了研究目的,所以忽略任何关于本机库更快的内容)。
我正在查看代码,C 代码直接将 转换float
为int
带有一些 C 指针魔法的。如果您尝试在 Java 中使用强制转换来执行此操作,则它不起作用:java 会截断浮点数(正如您所期望的那样),并且您无法获得原始指针(就像在 C 中那样)。那么你是怎么做到的呢?
如果事实证明你不需要它,或者它在你使用的 CPU 架构上速度较慢,那么最好不要在你的项目中使用这个钝代码。
Java 库有一种方法可以从浮点数获取原始位。
正如java.lang.Float
( http://docs.oracle.com/javase/6/docs/api/java/lang/Float.html ) 的 Javadoc 中所见,我们拥有该floatToIntBits
功能,以及intBitsToFloat
.
这意味着我们可以用 Java 编写“快速反平方根”,如下所示:
public static float invSqrt(float x) {
float xhalf = 0.5f * x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i >> 1);
x = Float.intBitsToFloat(i);
x *= (1.5f - xhalf * x * x);
return x;
}
这是双打的版本:
public static double invSqrt(double x) {
double xhalf = 0.5d * x;
long i = Double.doubleToLongBits(x);
i = 0x5fe6ec85e7de30daL - (i >> 1);
x = Double.longBitsToDouble(i);
x *= (1.5d - xhalf * x * x);
return x;
}
来源:http ://www.actionscript.org/forums/showthread.php3?t=142537
对于 Riking 的回答,即使是双倍也可以返回 0.9983227945440889 之类的东西作为一的平方根。
为了提高准确性,您可以使用我制作的这个版本:
public static double Q_rsqrt(double number){
double x = number;
double xhalf = 0.5d*x;
long i = Double.doubleToLongBits(x);
i = 0x5fe6ec85e7de30daL - (i>>1);
x = Double.longBitsToDouble(i);
for(int it = 0; it < 4; it++){
x = x*(1.5d - xhalf*x*x);
}
x *= number;
return x;
}
您可以根据需要编辑 for 循环终止前多长时间,但 4 次似乎可以将其降低到双精度的最大精度。如果你想要完美的准确性(或者如果你不应该打扰你的长小数字符串),请使用这个版本。