需要帮助将代码从C转换为Java

时间:2010-05-11 14:41:47

标签: java c translation

来自this文章。这是代码:

float InvSqrt(float x){ // line 0
   float xhalf = 0.5f * x;
   int i = *(int*)&x; // store floating-point bits in integer
   i = 0x5f3759d5 - (i >> 1); // initial guess for Newton's method
   x = *(float*)&i; // convert new bits into float
   x = x*(1.5f - xhalf*x*x); // One round of Newton's method
   return x;
}

......我甚至不知道那是C还是C ++。 [好吧显然它是C,谢谢]有人可以为我翻译成Java吗?它(只是,我希望)第2和第4行令我感到困惑。

5 个答案:

答案 0 :(得分:10)

您想使用以下方法:

strictfp等可能存在问题。

大致是这样的:(注意:这是未经测试的!)

float InvSqrt(float x){ // line 0
   float xhalf = 0.5f * x;
   int i = Float.floatToIntBits(x); // store floating-point bits in integer
   i = 0x5f3759d5 - (i >> 1); // initial guess for Newton's method
   x = Float.intBitsToFloat(i); // convert new bits into float
   x = x*(1.5f - xhalf*x*x); // One round of Newton's method
   return x;
}

答案 1 :(得分:7)

这些行用于在floatint之间转换为位模式。 Java在java.lang.Float中有静态方法 - 其他一切都是相同的。

static float InvSqrt(float x) { // line 0
    float xhalf = 0.5f * x;
    int i = Float.floatToIntBits(x); // store floating-point bits in integer
    i = 0x5f3759d5 - (i >> 1); // initial guess for Newton's method
    x = Float.intBitsToFloat(i); // convert new bits into float
    x = x * (1.5f - xhalf * x * x); // One round of Newton's method
    return x;
}

答案 2 :(得分:2)

你引用的代码是C,尽管注释是C ++风格的。

代码正在做什么涉及在位级别存储浮点值的方式。 “幻数”0x5f3759d5与特定值有关。

初始化x时访问浮点i值的位,因为x的地址被解除引用。因此,i加载了浮点值的前32位。在下一行,使用x的内容编写i,更新工作近似值。

我已经读过这个代码在John Carmack用Id的开源Quake引擎发布它时变得很流行。代码的目的是快速计算1 / Sqrt(x),用于图形引擎的照明计算。

我无法将此代码直接转换为Java,因为它使用了如上所述的“类型双关语” - 当它访问内存中的float时就好像它是一个int。 Java阻止了这种活动,但正如其他人所指出的那样,Float对象提供了围绕它的方法。

在C中使用这个奇怪的实现的目的是为了它非常快。在编写本文时,我想这个方法有了很大的改进。我想知道今天的差异是否值得,当浮点运算变得更快时。

使用Java方法将float转换为整数位并返回可能比直接使用Java数学函数直接计算平方根而言要慢一些。

答案 3 :(得分:1)

好的,我现在出去了,因为我知道C,但我不懂Java。

用Java直接重写这个C代码是在乞求麻烦。 即使在C语言中,代码也是不可移植的。 除其他外,它依赖于:   浮点数的大小。   整数的大小。   浮点数的内部表示。   浮点数和整数的字节对齐方式。   使用逻辑右移实现右移(即i> 1)   算术右移(相对于算术右移)   具有高阶1位的整数因此不再等于除   2)。

我理解Java编译为字节码而不是直接编译 机器代码。字节码解释器的实现者使用调优 假设基于字节码的规范和理解 编译器从合理输入源输出的内容 码。

像这样的黑客不属于“明智的输入源”。

没有理由期望口译员会表现出来 你的C hack更快,实际上有很好的机会 它会慢一些。

我的建议是:IGNORE C代码。

寻找以Java为中心的效率提升。

C hack的概念是:

通过利用内部知识获得大约1 /平方(x) 浮点数的表示已经有了 指数被打破了数字,指数(x)/ 2更快 如果你已经有指数(x),则计算比root(x)。

然后hack执行牛顿方法的一次迭代 减少近似误差。我相信 一次迭代将错误减少到可容忍的程度。

也许这个概念值得在Java中进行调查, 但细节将取决于对亲密的了解 如何实现JAVA,而不是C的实现方式。

答案 4 :(得分:0)

你关心的线条非常简单。第2行采用float x中的字节,这些字节位于某些浮点表示形式,如IEEE754,并将它们存储为整数,与它们完全相同。这将导致完全不同的数字,因为整数和浮点数以字节形式表示不同。第4行相反,并将该int中的字节再次传递给float