LeetCode 67題題解。
想必經典的模擬加法大家都會,所以看到這題的時候,我就知道一定會有人用BigInt;果然如此。但是那位並沒有解釋BigInt的相關內容,只是給出了答案,所以這裏主要是介紹一下BigInt的內容。先來看寫法:
function addBinary(a: string, b: string): string {
return (BigInt("0b" + a) + BigInt("0b" + b)).toString(2);
}
關於這個寫法,可能存在三個疑問:
- 爲什麼要在a、b前面加上一個
0b
? toString
輸出是否正常,會不會帶上控制檯輸出時結尾的n?- 兼容性怎麼樣?
我們也知道,js / ts裏的最大安全整數是253 - 1,超出這個範圍的整數運算就不再準確(比如著名的2**53 === 2**53 + 1
)或無法表示了。爲了解決這個問題,就有了BigInt提案(一開始似乎是叫Integer),並且在ES10中成爲規範;這是BigInt的歷史背景。也是因爲這個原因,BigInt不能和number互操作,必須進行類型轉換,而且在轉換過程中可能會丟失精度。
關於第一個問題,如果不考慮題目中給的數據範圍,其實我們的第一反應應該是用parseInt
:
function addBinary(a: string, b: string): string {
return (parseInt(a, 2) + parseInt(b, 2)).toString(2);
}
在這種情況下,是不需要加上0b
的,因爲已經在parseInt
中指定了是二進制。但BigInt的構造函數只有一個參數,所以需要加上這個前綴來表明這是一個代表二進制數的字符串(0B
也行)。
關於第二個問題,因爲console.log
是一個非官方規範,每個瀏覽器有自己的實現,所以控制檯輸出和toString
方法的輸出沒有必然聯繫。而且文檔也說明了,BigInt的toString
不會帶上結尾的n。有一個很有意思的事,就是BigInt沒有-0
;不過跟這個話題沒什麼關係。
關於第三個問題,這個特性目前還沒有穩定,兼容性只有70%多。但是主流瀏覽器已經兼容,而且也有polyfill,所以兼容性不是一個很大的問題。