你天真的標量的算法不提供正確圓潤轉換 - 它將從某些輸入雙舍入受損。例如:如果x
爲0x88000081
,則正確舍入的轉換爲浮點數的結果爲2281701632.0f
,但您的標量算法將返回2281701376.0f
。
關閉我的頭頂,你可以做一個正確的轉換如下(我說的,這是從我的頭頂,所以很可能可以節約的地方的指令):
movdqa xmm1, xmm0 // make a copy of x
psrld xmm0, 16 // high 16 bits of x
pand xmm1, [mask] // low 16 bits of x
orps xmm0, [onep39] // float(2^39 + high 16 bits of x)
cvtdq2ps xmm1, xmm1 // float(low 16 bits of x)
subps xmm0, [onep39] // float(high 16 bits of x)
addps xmm0, xmm1 // float(x)
其中常數具有下列值:
mask: 0000ffff 0000ffff 0000ffff 0000ffff
onep39: 53000000 53000000 53000000 53000000
這樣做是分別高和各車道的低半部轉換爲浮點,再加入這些轉換後的值一起。因爲每一半隻有16位寬,所以轉換爲浮點數不會導致舍入。只有在添加兩半時纔會發生舍入;因爲添加是一個正確的四捨五入操作,整個轉換正確舍入。
相比之下,您的樸素實現首先將低31位轉換爲浮點數,這會導致舍入,然後有條件地將2^31添加到該結果中,這可能會導致第二次舍入。任何時候,如果您在轉換中有兩個單獨的舍入點,除非您非常小心它們的發生方式,否則不應指望結果正確舍入。
你的意思是截斷/舍入/ ...?你能舉一個最簡單的例子來說明所需的輸入/輸出嗎? – 2012-02-05 18:20:15
添加編輯來澄清 – 2012-02-05 18:48:07
我很困惑,你是否想將'int'轉換爲'float'或'float'爲'int'或兩者?你能否糾正問題的標題和/或身體,使其不那麼模糊? – 2012-02-05 19:08:43