Rik*_*ing 13 java floating-point square-root
我听说过这里讨论的"快速反平方根",我想将它放在我的Java程序中(仅用于研究目的,因此忽略有关本机库的任何更快的事情).
我正在查看代码,而C代码直接将其float转换为int带有一些C指针魔法的代码.如果你试图在带有强制转换的Java中执行此操作,它就不起作用:java会截断浮动(正如您所期望的那样),并且您无法获取基元的指针(就像在C中一样).那你怎么做的?
Rik*_*ing 20
如果事实证明你不需要它,或者你在使用的CPU架构上速度较慢,那么最好不要在你的项目中使用这个钝的代码.
Java库有一种从浮点数到原始位的方法.
正如Javadoc for java.lang.Float(http://docs.oracle.com/javase/6/docs/api/java/lang/Float.html)中所见,我们有这个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;
}
Run Code Online (Sandbox Code Playgroud)
这是双打的版本:
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;
}
Run Code Online (Sandbox Code Playgroud)
资料来源: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;
}
Run Code Online (Sandbox Code Playgroud)
您可以编辑for循环终止之前多长时间,但是4次似乎可以将其降低到双精度的最大精度.如果你想要完美的准确性(或者如果他们不应该打扰你的长串小数),请使用此版本.
| 归档时间: |
|
| 查看次数: |
7333 次 |
| 最近记录: |