2010-03-16 63 views
0

是否有一個快速的方法來獲取浮點數的模數?快速,矢量化方法取特殊素數的浮點數模數?

對於整數,梅森素數有一些技巧,所以可以計算y = x MOD 2^31-1而不需要除法。 integer trick

可以使用任何類似的技巧來應用浮點數嗎?

優選地,以可以轉換成向量/ SIMD操作或移入GPGPU代碼的方式。這排除了對浮點數據使用整數計算。

我感興趣的素數將是2^7-1和2^31-1,但如果浮點數的效率更高,那麼將會受到歡迎。

該算法的一個預期用途是在輸入浮點數正在讀入算法時計算運行的「校驗和」。爲了避免佔用太多的計算能力,我想保持這種輕量級。

顯然類似的技術被用於更大的數字,特別是2^127 - 1.不幸的是,本文中的數學超出了我,我還沒有弄清楚如何將它轉換爲更小的素數。
Example of floating point MOD 2^127 - 1 - HASH127

+1

這是可能的計算任何冪的兩個模數沒有劃分;你確定你在問你打算的問題嗎?我相信你實際上是在尋找計算mod'2^7 - 1'和'2^31 - 1'。 – 2010-03-16 20:00:21

+0

2^7和2^31不是素數 - 你能更準確地更改一下你的問題嗎? – 2010-03-16 20:02:13

+0

您定位了哪些指令集? – user287792 2010-03-17 16:58:48

回答

1

我看了一下djb的論文,你可以更容易一些,因爲31位可以很好地適用於53位精度雙倍有效位。假設您的校驗和包含Z /(2 ** 31 - 1)上的一些環形運算,解決計算x mod Z /(2 ** 31 - 1)的小代表的輕鬆問題將更容易(也更快) 1);最後,你可以使用整數算術來尋找一個規範的算法,雖然速度很慢,但不應該經常發生。

基本還原步驟是用y + z替換整數x = y + 2 ** 31 * z。 djb使用的技巧是計算w =(x + L) - L,其中L是一個精心挑選的大整數,以z = 2 ** - 31 * w的方式來引起舍入。然後計算y = x - w和輸出y + z,它的最大幅度爲2 ** 32。 (我對此操作不夠充分表示歉意;如果是這樣,請發佈校驗和算法。)

L的選擇涉及知道有效數字的精確程度。對於模數2 ** 31 - 1,我們希望最小精度單位(ulp)爲2 ** 31。對於範圍[1.0,2.0)的雙打,ulp是2 ** - 52,所以L應該是2 ** 52 * 2 ** 31。如果你是用模數2 ** 7 - 1來做這個,那麼你會取L = 2 ** 52 * 2 ** 7。正如djb所指出的,這個技巧主要取決於中間結果而不是的計算精度更高。

+0

我想到的校驗和只是將數字相加在一起,並將結果模數作爲素數。我對你的迴應還是有點困惑。 X是當前校驗和,y是我正在添加的數字。兩者都在整數範圍0 ... 2 ** 31中。即使我四捨五入,我如何計算模數? – caffiend 2010-05-02 19:50:05