是否可以使用JavaScript中的类型化数组将4x Uint8转换为Uint32? [英] Is it possible to convert from 4x Uint8 into Uint32 using typed arrays in JavaScript?

查看:147
本文介绍了是否可以使用JavaScript中的类型化数组将4x Uint8转换为Uint32?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在项目中进行一些按位操作,我想知道内置的类型化数组是否可以使我省去一些麻烦,甚至可能会给我带来一些性能提升.

I'm doing some bitwise manipulation in a project and I wonder if the built-in typed arrays might save me some headache and maybe even give me a bit of a performance gain.

let bytes = [128, 129, 130, 131]
let uint32 = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]
//=> -2138996093

我可以使用类型数组来获得相同的答案吗?

// not actually working !
let uint8bytes = Uint8Array.from(bytes)
let uint32 = Uint32Array.from(uint8bytes)[0]
//=> ideally i'd get the same value as above: -2138996093


侧面问题:

我发现上面的uint32是负数很奇怪-显然不是很... unsigned ,就像var的名字暗示的那样...

I found it strange that the uint32 above is negative – obviously not very ... unsigned as the name of the var suggests ...

如果我将二进制八位字节混合在一起并进行解析,我会得到免费的肯定答案

If I mash together binary octets and parse it, I get the complimentary positive answer

//         128          129          130          131
let bin = '10000000' + '10000001' + '10000010' + '10000011'
let uint32 = Number.parseInt(bin,2)

console.log(uint32)
// 2155971203 

我可以逆转过程以从每个过程中获取正确的值也就不足为奇了,但是我不明白为什么过程1为负而过程2为正.

It's no surprise that I can reverse the process to get the correct values out of each, but I don't understand why procedure 1 is negative but procedure 2 is positive.

let a = -2138996093;
let b = 2155971203;

// two's compliment, right?
console.log(a.toString(2)) // -1111111011111100111110101111101
console.log(b.toString(2)) // 10000000100000011000001010000011

console.log(a >> 24 & 255) // 128
console.log(a >> 16 & 255) // 129
console.log(a >> 8 & 255)  // 130
console.log(a >> 0 & 255)  // 131

console.log(b >> 24 & 255) // 128
console.log(b >> 16 & 255) // 129
console.log(b >> 8 & 255)  // 130
console.log(b >> 0 & 255)  // 131

推荐答案

处理此问题的最佳方法是使用DataView-这样,您可以指定要获取的值的字节序-您的代码将bigendian值用于int32

The best way to handle this is with a DataView - that way you can specify the endianness of the value you want to get - your code is using bigendian values for the int32

let bytes = [128, 129, 130, 131];
let uint8bytes = Uint8Array.from(bytes);
let dataview = new DataView(uint8bytes.buffer);
let int32le = dataview.getInt32(0, true); // second parameter truethy == want little endian
let int32be = dataview.getInt32(0); // second parameter absent or falsey == want big endian
console.log(int32le); // -2088599168
console.log(int32be); // -2138996093

原因

let uint32 = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]

返回SIGNED整数是按位运算符(<<|)将值强制转换为有符号的32位值

returns a SIGNED int is that the bitwise operators (<<, |) coerce the values to a signed 32 bit value

这篇关于是否可以使用JavaScript中的类型化数组将4x Uint8转换为Uint32?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆