打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
如何从JavaScript中的ArrayBuffer / DataView读取64位整数

给定一个64位(8字节)的little-endian ArrayBuffer字节,我们如何在JavaScript中读取64位整数值?

我进行了实验并想出了这个,但是有一个更优雅的解决方案,因为DataView还没有提供getUint64()吗?

const bytes = new Uint8Array([ 0xff,0xff,0xff,0xff,   0xff,0xff,0xff,0xff ]);//                             [-----  left  -----]   [----  right  ----] const view = new DataView(bytes.buffer);// split 64-bit number into two 32-bit numbersconst left = view.getUint32(0, true);  // 4294967295const right = view.getUint32(4, true); // 4294967295// combine the 2 32-bit numbers using max 32-bit val 0xffffffffconst combined = left   2**32*right;console.log('combined', combined);// 18,446,744,073,709,552,000  is returned Javascript for "combined"// 18,446,744,073,709,551,615  is max uint64 value// some precision is lost since JS doesn't support 64-bit ints, but it's close enough

解决方法:

基于原始实验和Sebastian Speitel的建议/修复,此函数返回64位值,直到Number.MAX_SAFE_INTEGER之后精度丢失

DataView.prototype.getUint64 = function(byteOffset, littleEndian) {  // split 64-bit number into two 32-bit parts  const left =  this.getUint32(byteOffset, littleEndian);  const right = this.getUint32(byteOffset 4, littleEndian);  // combine the two 32-bit values  const combined = littleEndian? left   2**32*right : 2**32*left   right;  if (!Number.isSafeInteger(combined))    console.warn(combined, 'exceeds MAX_SAFE_INTEGER. Precision may be lost');  return combined;}

测试如下:

// [byteArray, littleEndian, expectedValue]const testValues = [  // big-endian  [new Uint8Array([0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0xff]),  false, 255],   [new Uint8Array([0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0xff, 0xff]),  false, 65535],  [new Uint8Array([0x00, 0x00, 0x00, 0x00,  0xff, 0xff, 0xff, 0xff]),  false, 4294967295],  [new Uint8Array([0x00, 0x00, 0x00, 0x01,  0x00, 0x00, 0x00, 0x00]),  false, 4294967296],  [new Uint8Array([0x00, 0x1f, 0xff, 0xff,  0xff, 0xff, 0xff, 0xff]),  false, 9007199254740991], // maximum precision  [new Uint8Array([0x00, 0x20, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00]),  false, 9007199254740992], // precision lost  [new Uint8Array([0x00, 0x20, 0x00, 0x00,  0x00, 0x00, 0x00, 0x01]),  false, 9007199254740992], // precision lost  // little-endian  [new Uint8Array([0xff, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00]),  true, 255],   [new Uint8Array([0xff, 0xff, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00]),  true, 65535],  [new Uint8Array([0xff, 0xff, 0xff, 0xff,  0x00, 0x00, 0x00, 0x00]),  true, 4294967295],  [new Uint8Array([0x00, 0x00, 0x00, 0x00,  0x01, 0x00, 0x00, 0x00]),  true, 4294967296],  [new Uint8Array([0x00, 0x00, 0x00, 0x00,  0x00, 0x01, 0x00, 0x00]),  true, 1099511627776],  [new Uint8Array([0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x01, 0x00]),  true, 281474976710656],  [new Uint8Array([0xff, 0xff, 0xff, 0xff,  0xff, 0xff, 0x1f, 0x00]),  true, 9007199254740991], // maximum precision];testValues.forEach(testGetUint64);function testGetUint64([bytes, littleEndian, expectedValue]) {  const val = new DataView(bytes.buffer).getUint64(0, littleEndian);  console.log(val === expectedValue? 'pass' : 'FAIL. expected ' expectedValue ', received ' val);}
来源:https://www.icode9.com/content-1-493551.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
JavaScript 操作二进制数据简单指北-ArrayBuffer
JavaScript 之 ArrayBuffer
JavaScript奇技淫巧:执行“二进制”代码
cve-2016-1646漏洞完整利用源码(荐)
理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型 ? 张鑫旭
JavaScript的“强类型数组”简介
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服