如何在JavaScript中进行数字类型转换?
a = (unsigned int)atoi(arg1);
b = (unsigned int)atoi(arg2);
假设a和b可以被标记为有符号数。我想将一个4字节的有符号整数转换为4字节的无符号整数。
我知道在JavaScript中不存在类型转换或有符号/无符号。我正在寻找一种易于理解的算法。
如何在JavaScript中进行数字类型转换?
a = (unsigned int)atoi(arg1);
b = (unsigned int)atoi(arg2);
假设a和b可以被标记为有符号数。11111111111111111111111111111011
,当解释为无符号整数时,它是4294967291。在无符号整数运算中,0减去5得到的结果就是这个。 - Vatev(new Uint32Array([arg1]))[0]
e.g.
< (new Uint32Array([-1]))[0]
> 4294967295
将有符号字节转换为无符号字节,JavaScript:
-5 & 0xff // = 251 , signed to unsigned byte
251 <<24 >>24 // = -5 , unsinged byte to signed
第一个操作将除了第一个字节之外所有的第一个位都变成0
第二个操作可以在以下链接中找到:
https://blog.vjeux.com/2013/javascript/conversion-from-uint8-to-int8-x-24.html
简单来说,一个数字有4个字节。对于正数来说,前3个字节是0,并且所有的0比特都是0。对于负数来说,前3个字节是1,并且所有的0比特都是1,而所有的1比特都是0。在字节中,第4个字节的最高比特用于表示符号;
将比特向左移动使得第一个字节的第一个比特变为第四个字节的第一个比特,然后再向右移动,就可以拖动最高有效比特。所以如果符号比特为1,则会在前3个字节中产生许多1比特。因此这是一个移位的副作用,但它起作用。
for example: like you start from
?1111111 the first bit is a sign bit - ?,
but in a larger variable, so it is:
00000000_00000000_00000000_?1111111
shift to left
?1111111_........_........_........
shift to right
????????_????????_????????_?1111111
this is the effect,
it drags the edge bit across the shift
Javascript中的所有(原始)数字都是IEEE748双精度浮点数,提供了52位整数精度。
有符号和无符号的问题在于,除了>>>
之外的所有Javascript位运算符都将数字转换为32位的有符号数字——也就是说,它们取最低有效32位并且舍去其余部分,然后将结果的第31位作为符号扩展以给出带符号的结果。
如果您从已知的四个字节值开始,则可以通过使用简单的乘法和加法来绕过位运算符的问题,这些运算符使用了所有52位的整数精度,例如:
var a = [ 1, 2, 3, 4]; // 0x01020304
var unsigned = a[0] * (1 << 24) + a[1] * (1 << 16) + a[2] * (1 << 8) + a[3]
TypedArray可以使这个过程变得更容易:
const int32SignedToUnsigned = (int32) => Uint32Array.from(Int32Array.of(int32))[0];
const int32UnsignedToSigned = (uint32) => Int32Array.from(Uint32Array.of(uint32))[0];
// Examples:
console.log('with expected inputs:')
console.log(int32SignedToUnsigned(-1))
console.log(int32UnsignedToSigned(4294967295))
console.log(int32SignedToUnsigned(-2))
console.log(int32UnsignedToSigned(4294967294))
console.log('overflow behavior:')
console.log('int32UnsignedToSigned(4294967296):', int32UnsignedToSigned(4294967296))
console.log('int32SignedToUnsigned(4294967296):', int32SignedToUnsigned(4294967296))
console.log('int32UnsignedToSigned(-1):', int32UnsignedToSigned(-1))
console.log('int32SignedToUnsigned(-1):', int32SignedToUnsigned(-1))