簡體   English   中英

在將代碼從C轉換為Java方面需要幫助

[英]Need help in translating code from C to Java

這個文章。 這是代碼:

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行使我感到困惑。

您要使用以下方法:

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

這些行用於在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;
}

您引用的代碼是C,盡管注釋是C ++樣式的。

代碼正在執行的操作涉及在位級別上存儲浮點值的方式的知識。 “幻數” 0x5f3759d5與特定值有關。

初始化i時將訪問浮點x值的位,因為x的地址已取消引用。 因此, i加載了浮點值的前32位。 在下一行, x寫入i的內容,從而更新工作近似值。

我已經讀到,當約翰·卡馬克(John Carmack)與Id的開源Quake引擎一起發布該代碼時,它變得很流行。 該代碼的目的是快速計算1 / Sqrt(x),該值用於圖形引擎的光照計算。

我將無法直接將此代碼轉換為Java,因為它使用了如上所述的“類型校正”(當它像訪問int一樣訪問內存中的float時)。 Java阻止了這種活動,但是正如其他人指出的那樣,Float對象提供了圍繞它的方法。

在C中使用這種奇怪的實現的目的是為了使其非常快。 在撰寫本文時,我想這種方法會帶來很大的改進。 我不知道當浮點運算變得更快時,今天的差異是否值得。

使用Java方法將float轉換為整數位並返回,可能比直接使用Java數學函數求平方根簡單地計算平方根的倒數要慢。

好的,我在這里走了一步,因為我知道C,但是我不懂Java。

從字面上看,用Java重寫此C代碼很麻煩。 即使在C語言中,代碼也是不可移植的。 它依賴於其他因素:浮點數的大小。 整數的大小。 浮點數的內部表示。 浮點數和整數的字節對齊。 右移(即i >> 1)是使用邏輯右移實現的,而與算術右移相反(算術右移會在具有高階1位的整數上移1,因此不再等於2)。

我了解Java會編譯為字節碼,而不是直接編譯為機器碼。 字節碼解釋器的實現者使用基於字節碼規范的假設進行調整,並理解編譯器從明智的輸入源代碼輸出的內容。

這樣的黑客不屬於“明智的輸入來源”。

沒有理由期望解釋器會隨着您的C hack的執行而更快,實際上,很有可能它會變慢。

我的建議是:IGNORE C代碼。

尋找以Java為中心的效率提升。

C hack的概念是:

利用已知的浮點數的內部表示已經打破了指數的認識,近似為1 / square(x),如果您已經有了exponent(x),exponent(x)/ 2的計算比root(x)更快。 )。

然后,hack將執行牛頓方法的一次迭代,以減少近似誤差。 我假設一次迭代將錯誤減少到可以容忍的程度。

也許該概念值得用Java進行研究,但是細節將取決於對JAVA如何實現的深入了解,而不是C的實現方式。

您關心的行非常簡單。 第2行采用float x的字節,它們以某種浮點表示形式(如IEEE754)存儲在整數中,與它們的存儲方式完全相同。 這將導致完全不同的數字,因為整數和浮點數以字節形式表示的方式有所不同。 第4行做相反的事情,然后將int中的字節再次傳輸到float

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM