关于位操作:在 JavaScript 中减去有符号整数

Subtract signed integers in JavaScript

我想在 JavaScript 中减去两个有符号的 8 位整数。由于 JavaScript 没有 \\'signed\\' 或 \\'unsigned\\' 整数的类型,我需要坚持使用 \\'number\\' 类型 - 并且不能像它那样做一些 \\'cast-magic\\'可以使用不同的语言。

我想模拟一种 CPU 寄存器,因此需要同时处理有符号和无符号值。此外,我需要计算进位和溢出标志的值。进位标志在发生无符号溢出时设置(无符号值已离开 0 到 255 的范围),而溢出标志在有符号溢出时设置(值不在 -128 - 127 范围内)。

这段代码似乎可以工作,但相当麻烦和丑陋。有没有"简单"的方法来做这个计算?

提前致谢!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//Convert a signed 8bit number to a"real" number (254 => -2)
function toSigned(number)
{
    if (number & 0x80) //sign bit is set
        number = -(0x100 - number);
    return number
}
//Inverts the sign of a signed 8bit number
function invertSign(number)
{
    return 0x100 - number;
}
//subtracts source from target
function sub(target,source)
{
    //calculate carry
    var carry = (target - source < 0);
    console.log("Carry: %b", carry);

    //Calculate result & overflow
    var result = (target + invertSign(source)) & 0xFF;
    var overflow = !(result >= -128 && result <= 127);
    console.log("Overflow: %b", overflow);
    console.log("Result: %d - %d = %d",toSigned(target),toSigned(source),result);
}
//Examples
sub(8,254); //8 - (-2), no overflow, carry set
sub(8,2); //8 - 2, no overflow, no carry
sub(0x50,0xB0); //80 - (-80), overflow, carry


似乎对您来说最好的选择之一是 Typed Arrays(并非所有浏览器都完全支持,请参阅我可以使用:typedarrays)

1
2
3
4
5
6
var signed8bitArray = new Int8Array(1);
var unsigned8bitArray = new Uint8Array(1);

unsigned8bitArray[0] = 254;
signed8bitArray[0] = unsigned8bitArray[0];
signed8bitArray[0] == -2 // This is true

您可能想阅读来自 MDN 的 Int8ArrayUint8Array 和有关 JavaScript 类型数组的一般文档。