摘要:由于這個原因,在一些需要更精確運算的應用場景中,精度就不夠了,例如需要把位數(shù)字寫入到數(shù)組中。但是這又如何在中讀寫位數(shù)據(jù)操作中位數(shù)據(jù)的方案寫一個,在項目中引入,以下例子為使用方式與類似使用的得出的結(jié)果應該與原生方法保持一致的。
JS 的 Uint53
JS 的 Number 精度只有 「-2^52 ~ 2^52 - 1」,可以通過 Number.MAX_SAFE_INTEGER 查看 JS 的安全運算范圍。
由于這個原因,在一些需要更精確運算的應用場景中,JS Number 精度就不夠了,例如需要把 64 位數(shù)字寫入到 buffer 數(shù)組中。
那怎么解決 JS 的精度問題?
使用 BigInt在最新的 stage3 中,引入了 BigInt API,用于解決超出 JS Number 運算范圍的精度問題。
打開瀏覽器的控制臺輸入
BigInt(0) // 輸出 0n
在數(shù)字后面加 n 就是 BigInt 類型。
有 BigInt API 可以輕松向 buffer 寫入 64 位的數(shù)據(jù)
const buffer = new ArrayBuffer(8); const view = new DataView(buffer); const offset = 0; const littleEndian = true; view.setBigUint64(offset, BigInt("123456789012412421521"), littleEndian); console.log(view) // 剛好用 64 字節(jié)寫滿 8 位的 buffer
但是事情并沒有那么一帆風順,目前只有 Chrome 和 Firefox 等主流瀏覽器實現(xiàn)了,Safari 系列的 javascriptCore 引擎并不支持,需要用另外的方法兼容。
如何兼容不支持 BigInt 的 js 引擎?
使用 Chrome 團隊出品的 JSBIJSBI GitHub
可以兼容大數(shù)據(jù)運算的需求
import JSBI from "jsbi" // 官方例子,用 JS 最大長度 + 2 const max = JSBI.BigInt(Number.MAX_SAFE_INTEGER); console.log(String(max)); // → "9007199254740991" const other = JSBI.BigInt("2"); const result = JSBI.add(max, other); console.log(String(result));
恨簡單的使用方式,完美兼容。
但是這又如何在 buffer 中讀寫 64 位數(shù)據(jù)?
操作 buffer 中 64 位數(shù)據(jù)的方案寫一個 polyfill,在項目中引入,以下例子為 TS
import JSBI from "jsbi"; declare global { interface DataView { setUint64: Function; getUint64: Function; } } DataView.prototype.setUint64 = function setUint64( byteOffset: number, value, littleEndian: boolean ) { if (typeof value === "bigint" && typeof this.setBigUint64 !== "undefined") { // the original native implementation for bigint this.setBigUint64(byteOffset, value, littleEndian); } else if (value.constructor === JSBI && typeof value.sign === "bigint" && typeof this.setBigUint64 !== "undefined") { // JSBI wrapping a native bigint this.setBigUint64(byteOffset, value.sign, littleEndian); } else if (value.constructor === JSBI) { // JSBI polyfill implementation const lowWord = value[0]; let highWord = 0; if (value.length >= 2) { highWord = value[1]; } this.setUint32(byteOffset + (littleEndian ? 0 : 4), lowWord, littleEndian); this.setUint32(byteOffset + (littleEndian ? 4 : 0), highWord, littleEndian); } else { throw TypeError("Value needs to be BigInt ot JSBI"); } }; DataView.prototype.getUint64 = function getUint64(byteOffset, littleEndian) { if (typeof this.getBigUint64 !== "undefined") { return this.getBigUint64(byteOffset, littleEndian); } let lowWord = 0; let highWord = 0; lowWord = this.getUint32(byteOffset + (littleEndian ? 0 : 4), littleEndian); highWord = this.getUint32(byteOffset + (littleEndian ? 4 : 0), littleEndian); const result = new JSBI(2, false); result.__setDigit(0, lowWord); result.__setDigit(1, highWord); return result; };
使用方式與 BigInt 類似
import JSBI from "jsbi"; const buffer = new ArrayBuffer(8); const view = new DataView(buffer); const offset = 0; const littleEndian = true; // 使用 polyfill 的 api view.setUint64(offset, JSBI.BigInt("123456789012412421521"), littleEndian); console.log(view) // 得出的結(jié)果應該與原生方法保持一致的。參考
可以參考 little-chat IM 客戶端的實現(xiàn)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106346.html
摘要:二進制數(shù)組由三類對象組成對象視圖和視圖。目前,視圖一共包括種類型,每一種視圖都是一種構(gòu)造函數(shù)。位浮點數(shù),長度個字節(jié)這個構(gòu)造函數(shù)生成的數(shù)組,統(tǒng)稱為視圖。 編程風格 塊級作用域 let 取代 var,在let和const之間,建議優(yōu)先使用const,尤其是在全局環(huán)境,不應該設(shè)置變量,只應設(shè)置常量。 字符串 靜態(tài)字符串一律使用單引號或反引號,不使用雙引號。動態(tài)字符串使用反引號。 // goo...
摘要:涉及到計算機基礎(chǔ)知識,例如字節(jié)緩沖大小端等。是指用多少位表示的整數(shù),例如就是用位即一個字節(jié)表示的整數(shù),二進制范圍是,對應的十進制就是。開發(fā)時通訊雙方或者多方終端都遵循協(xié)議。 這里記錄了使用 protobuf 協(xié)議與服務(wù)端數(shù)據(jù)交互的相關(guān)內(nèi)容和知識。涉及到計算機基礎(chǔ)知識,例如字節(jié)、buffer 緩沖、大小端等。 字節(jié) / Byte 1 字節(jié)代表了 8 位(bit)二進制,1 位就是 0...
摘要:以上每個構(gòu)造函數(shù)都對應如下形式的參數(shù)可以指定序列化其中到部分的二進制數(shù)據(jù)。的構(gòu)造函數(shù)還接受另一個作為參數(shù),開辟新內(nèi)存復制其值,對原數(shù)組不構(gòu)成影響,也不共用內(nèi)存。 這個部分如果沒有C語言和計算機基礎(chǔ)會比較難理解,如果實在理解不了可以收藏它,日后再看。 二進制數(shù)組其實很早就有了,不過為了 WebGL 中,數(shù)據(jù)可以高效和顯卡交換數(shù)據(jù)。分為3類: ArrayBuffer:代表內(nèi)存中的一段二進...
摘要:簡介本篇文章主要探討中的數(shù)據(jù)操作一直以來給人一種比較低能的感覺例如無法讀取系統(tǒng)上的文件不能做一些底層的操作所以在頁面上操作數(shù)據(jù)會交由服務(wù)器處理也就成了主流的做法但是很多人沒有發(fā)現(xiàn)實際上以及在逐步增強這些功能現(xiàn)在我們就已經(jīng)可以放心的在端進行文 簡介 本篇文章主要探討JavaScript中的數(shù)據(jù)操作. JavaScript一直以來給人一種比較低能的感覺,例如無法讀取系統(tǒng)上的文件,不能做一些...
摘要:簡介本篇文章主要探討中的數(shù)據(jù)操作一直以來給人一種比較低能的感覺例如無法讀取系統(tǒng)上的文件不能做一些底層的操作所以在頁面上操作數(shù)據(jù)會交由服務(wù)器處理也就成了主流的做法但是很多人沒有發(fā)現(xiàn)實際上以及在逐步增強這些功能現(xiàn)在我們就已經(jīng)可以放心的在端進行文 簡介 本篇文章主要探討JavaScript中的數(shù)據(jù)操作. JavaScript一直以來給人一種比較低能的感覺,例如無法讀取系統(tǒng)上的文件,不能做一些...
閱讀 1361·2021-09-24 10:26
閱讀 3678·2021-09-06 15:02
閱讀 632·2019-08-30 14:18
閱讀 588·2019-08-30 12:44
閱讀 3128·2019-08-30 10:48
閱讀 1952·2019-08-29 13:09
閱讀 2006·2019-08-29 11:30
閱讀 2292·2019-08-26 13:36