Javascript:将(十六进制)有符号整数转换为javascript值

myt*_*hbu 7 javascript sign

我有一个以十六进制数给出的带符号值,例如,0xffeb并希望将其转换-21为"正常"Javascript整数.

到目前为止我写了一些代码:

function toBinary(a) { //: String
    var r = '';
    var binCounter = 0;
    while (a > 0) {
        r = a%2 + r;
        a = Math.floor(a/2);
    }
    return r;
}

function twoscompl(a) { //: int
    var l = toBinaryFill(a).length;
    var msb = a >>> (l-1);

    if (msb == 0) {
        return a;
    }

    a = a-1;
    var str = toBinary(a);
    var nstr = '';
    for (var i = 0; i < str.length; i++) {
        nstr += str.charAt(i) == '1' ? '0' : '1';
    }
    return (-1)*parseInt(nstr);
}
Run Code Online (Sandbox Code Playgroud)

问题是,我的函数为两个数字返回1作为MSB,因为只查看二进制表示"字符串"的MSB.对于这种情况,两个数字都是1:

-21 => 0xffeb => 1111 1111 1110 1011
 21 => 0x15   =>              1 0101
Run Code Online (Sandbox Code Playgroud)

您是否有任何想法实现这更高效和更好?

问候,mythbu

Bar*_*chs 13

使用parseInt()转换(这只是接受你的十六进制字符串):

parseInt(a);
Run Code Online (Sandbox Code Playgroud)

然后使用掩码来确定MSB是否已设置:

a & 0x8000
Run Code Online (Sandbox Code Playgroud)

如果返回非零值,则表示它为负数.

把它包起来:

a = "0xffeb";
a = parseInt(a, 16);
if ((a & 0x8000) > 0) {
   a = a - 0x10000;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于16位整数(short在C中).如果你有一个32位整数,你需要一个不同的掩码和减法.

  • 你应该减去`0x10000` (2认同)

mil*_*mns 10

我想出了这个

function hexToInt(hex) {
    if (hex.length % 2 != 0) {
        hex = "0" + hex;
    }
    var num = parseInt(hex, 16);
    var maxVal = Math.pow(2, hex.length / 2 * 8);
    if (num > maxVal / 2 - 1) {
        num = num - maxVal
    }
    return num;
}
Run Code Online (Sandbox Code Playgroud)

用法:

var res = hexToInt("FF"); // -1
res = hexToInt("A"); // same as "0A", 10
res = hexToInt("FFF"); // same as "0FFF", 4095
res = hexToInt("FFFF"); // -1
Run Code Online (Sandbox Code Playgroud)

所以基本上十六进制转换范围取决于十六进制的长度,这就是我正在寻找的.希望能帮助到你.


Kos*_*nha 6

基于@Bart Friederichs,我带来了:

function HexToSignedInt(num, numSize) {
    var val = {
        mask: 0x8 * Math.pow(16, numSize-1), //  0x8000 if numSize = 4
        sub: -0x1 * Math.pow(16, numSize)    //-0x10000 if numSize = 4
    }
    if((parseInt(num, 16) & val.mask) > 0) { //negative
        return (val.sub + parseInt(num, 16))
    }else {                                 //positive
        return (parseInt(num,16))
    }
 }
Run Code Online (Sandbox Code Playgroud)

所以现在您可以指定确切的长度(以半字节为单位)。

var numberToConvert = "CB8";
HexToSignedInt(numberToConvert, 3);
//expected output: -840
Run Code Online (Sandbox Code Playgroud)

  • 我真的很喜欢这个解决方案。我必须在否定检查中添加一个额外的括号才能通过所有测试。例如 HexToSignedInt("7d",2) if((parseInt(num, 16) &amp; val.mask) &gt; 0) { //负数 (2认同)