
我想使用Excel來乘以32位元整數並得到低32位。換句話說,給定數字 n1, n2,我想計算MOD(n1*n2, 2^32)
。但是,此公式在 Excel 中不起作用,因為(對於較大的 n1 和 n2),乘積超出了 Excel 的精度容量,因此對較低的數字進行四捨五入。我在使用 Excel 的同時有什麼辦法可以避免這種情況嗎?
我設法想出的一種原始解決方案是將其中一個數字分成 8 位元區塊並相應地相乘(MOD
在必要時使用截斷),但我希望尋找不那麼混亂的東西。
答案1
如果您使用的是 64 位元 Office,那麼您可以建立自訂函數並使用新的LongLong
類型計算。按Alt+F11開啟 Visual Basic 編輯器,點選插入 > 模組然後貼上下面的程式碼
Public Function MulMod32(number1, number2) As Double
Dim n1 As LongLong, n2 As LongLong
n1 = CLngLng(number1)
n2 = CLngLng(number2)
' Sign-extend the numbers
n1 = IIf((n1 And &H80000000&) = 0, n1, n1 Or &HFFFFFFFF00000000^)
n2 = IIf((n2 And &H80000000&) = 0, n2, n2 Or &HFFFFFFFF00000000^)
MulMod32 = CDbl((n1 * n2) And &HFFFFFFFF^)
End Function
之後您可以MulMod32()
在任何公式中使用,例如=MulMod32(HEX2DEC("fffffffe"), HEX2DEC("ffff1234"))
如果沒有,LongLong
那麼您可以將數字分成更小的部分來進行操作,但您不需要處理 8 位元區塊,因為 16 位元值就足夠了。如果我們有 a 和 b,那麼將它們拆分為 (ah, al) 和 (bh, bl) 後,它們的乘積可以這樣計算
a × b = (ah × 2 16 + al)(bh × 2 16 + bl) = ah × bh × 2 32 + (ah × bl + al × bh) × 2 16 + al × bl
因此,我們可以有 4 列 ah、al、bh、bl 和一列乘積,公式如下
A1 | B1 |
---|---|
啊 | =BITRSHIFT(a, 16) |
阿爾 | =BITAND(a, 65535) |
乙肝 | =BITRSHIFT(b, 16) |
BL | =BITAND(b, 65535) |
產品 | =BITAND(BITAND((ah*bl + bh*al), 65535)*2^16 + al*bl, 4294967295) |
答案2
如果你看規格和限制您會發現至少自 Excel 2007 以來有以下限制:
特徵 最大限制 數位精度 15 位數字 允許的最小負數 -2.2251E-308 允許的最小正數 2.2251E-308 最大允許正數 9.99999999999999E+307 最大允許負數 -9.99999999999999E+307 透過公式計算允許的最大正數 1.7976931348623158e+308 透過公式計算允許的最大負數 -1.7976931348623158e+308
正如您所看到的,根據您使用的數字,您將不可避免地失去精確度。
當您指定 32 位數字(假設為無符號整數)時,您需要計算的最大值將是 18,446,744,073,709,551,616 (2 32 *2 32 = 2 64 ),這顯然超出了 15 位數字的限制,儘管它沒有超出限制可以計算的最大數量。
此外,您計劃獲取結果的低 32 位,最好採用實際的程式設計或腳本語言來進行此類計算。
答案3
我設法想出的一個原始解決方案是將其中一個數字分成 8 位區塊並相應地相乘(必要時使用 MOD 截斷),但我希望找到一些不那麼混亂的東西。