javascript語言特性:Number的bitwise operation(位元操作)是使用32bit處理
最近想要移植C的一些64bit資料處理的小程式到JS上,就遭遇這個問題位元指令32bit的問題。實際上JS所有的位元操作(bitwise operation),諸如:左移(left shift)、右移(right shift)、OR、AND、XOR等都是只能用在32位元內操作。
舉例
1 << 30
得到 1073741824
1 << 31
得到 -2147483648
2147483647 & 0x01
得到 1
2147483648 | 0x01
得到 -2147483647
確認Number規格
查看Number的MDN說明,Number是使用double以IEEE754規格實作的,可以表示的整數範圍應是從-(2^53-1)至2^53- 1,但是為何我放不進去呢?
在AND運算的MDN說明跟一些網站教學有提到,JS的Bitwise都是32bit的
如何解決運算問題?
- 使用一般的加減乘除
- 使用BigInt
使用一般的加減乘除
例如上面的1 << 31,就改成 1 * 2 ** 31,可以得到 2147483648
使用BigInt
轉成BigInt只需要使用BigInt函數處理即可,不用new運算子。
var value = BigInt(2147483648);
而literal的部份則是多加上n,就可指定使用BigInt,例如
value | 0x01n
得到 2147483649n
!!注意!! 如果你的運算中間沒有都使用BigInt會產生TypeError的錯誤,訊息如下
Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions at ....
如何從BigInt轉回Number?
用Number轉型就可以轉回來,例如Number(2147483649n)可得到2147483649,不過如果超過Number可表現的範圍也一樣會錯誤喔
如何判斷BigInt類型?
typeof value === "bigint"
題外話: 你可以測試看看下面這些的結果
2**53-1
2**53
2**53+1
2**53+2
2**53+3
2**53+4
Number(2n**53n-1n)
Number(2n**53n)
Number(2n**53n+1n)
Number(2n**53n+2n)
Number(2n**53n+3n)
Number(2n**53n+4n)
留言