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