摘要:由于這個原因,在一些需要更精確運算的應用場景中,精度就不夠了,例如需要把位數字寫入到數組中。但是這又如何在中讀寫位數據操作中位數據的方案寫一個,在項目中引入,以下例子為使用方式與類似使用的得出的結果應該與原生方法保持一致的。
JS 的 Uint53
JS 的 Number 精度只有 「-2^52 ~ 2^52 - 1」,可以通過 Number.MAX_SAFE_INTEGER 查看 JS 的安全運算范圍。
由于這個原因,在一些需要更精確運算的應用場景中,JS Number 精度就不夠了,例如需要把 64 位數字寫入到 buffer 數組中。
那怎么解決 JS 的精度問題?
使用 BigInt在最新的 stage3 中,引入了 BigInt API,用于解決超出 JS Number 運算范圍的精度問題。
打開瀏覽器的控制臺輸入
BigInt(0) // 輸出 0n
在數字后面加 n 就是 BigInt 類型。
有 BigInt API 可以輕松向 buffer 寫入 64 位的數據
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 字節寫滿 8 位的 buffer
但是事情并沒有那么一帆風順,目前只有 Chrome 和 Firefox 等主流瀏覽器實現了,Safari 系列的 javascriptCore 引擎并不支持,需要用另外的方法兼容。
如何兼容不支持 BigInt 的 js 引擎?
使用 Chrome 團隊出品的 JSBIJSBI GitHub
可以兼容大數據運算的需求
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 位數據?
操作 buffer 中 64 位數據的方案寫一個 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) // 得出的結果應該與原生方法保持一致的。參考
可以參考 little-chat IM 客戶端的實現
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106346.html
摘要:二進制數組由三類對象組成對象視圖和視圖。目前,視圖一共包括種類型,每一種視圖都是一種構造函數。位浮點數,長度個字節這個構造函數生成的數組,統稱為視圖。 編程風格 塊級作用域 let 取代 var,在let和const之間,建議優先使用const,尤其是在全局環境,不應該設置變量,只應設置常量。 字符串 靜態字符串一律使用單引號或反引號,不使用雙引號。動態字符串使用反引號。 // goo...
摘要:涉及到計算機基礎知識,例如字節緩沖大小端等。是指用多少位表示的整數,例如就是用位即一個字節表示的整數,二進制范圍是,對應的十進制就是。開發時通訊雙方或者多方終端都遵循協議。 這里記錄了使用 protobuf 協議與服務端數據交互的相關內容和知識。涉及到計算機基礎知識,例如字節、buffer 緩沖、大小端等。 字節 / Byte 1 字節代表了 8 位(bit)二進制,1 位就是 0...
摘要:以上每個構造函數都對應如下形式的參數可以指定序列化其中到部分的二進制數據。的構造函數還接受另一個作為參數,開辟新內存復制其值,對原數組不構成影響,也不共用內存。 這個部分如果沒有C語言和計算機基礎會比較難理解,如果實在理解不了可以收藏它,日后再看。 二進制數組其實很早就有了,不過為了 WebGL 中,數據可以高效和顯卡交換數據。分為3類: ArrayBuffer:代表內存中的一段二進...
摘要:簡介本篇文章主要探討中的數據操作一直以來給人一種比較低能的感覺例如無法讀取系統上的文件不能做一些底層的操作所以在頁面上操作數據會交由服務器處理也就成了主流的做法但是很多人沒有發現實際上以及在逐步增強這些功能現在我們就已經可以放心的在端進行文 簡介 本篇文章主要探討JavaScript中的數據操作. JavaScript一直以來給人一種比較低能的感覺,例如無法讀取系統上的文件,不能做一些...
摘要:簡介本篇文章主要探討中的數據操作一直以來給人一種比較低能的感覺例如無法讀取系統上的文件不能做一些底層的操作所以在頁面上操作數據會交由服務器處理也就成了主流的做法但是很多人沒有發現實際上以及在逐步增強這些功能現在我們就已經可以放心的在端進行文 簡介 本篇文章主要探討JavaScript中的數據操作. JavaScript一直以來給人一種比較低能的感覺,例如無法讀取系統上的文件,不能做一些...
閱讀 1352·2021-09-24 10:26
閱讀 3664·2021-09-06 15:02
閱讀 616·2019-08-30 14:18
閱讀 581·2019-08-30 12:44
閱讀 3124·2019-08-30 10:48
閱讀 1946·2019-08-29 13:09
閱讀 2001·2019-08-29 11:30
閱讀 2288·2019-08-26 13:36