15

たとえば、16 進数として指定された符号付きの値があり、それを「通常の」Javascript 整数として0xffeb変換したいと考えています。-21

これまでにいくつかのコードを書きました:

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);
}

問題は、私の関数が両方の数値の MSB として 1 を返すことです。これは、バイナリ表現の「文字列」の MSB のみが検索されるためです。この場合、両方の数値は 1 です。

-21 => 0xffeb => 1111 1111 1110 1011
 21 => 0x15   =>              1 0101

これをより効率的かつ適切に実装するアイデアはありますか?

こんにちは、神話

4

5 に答える 5

25

Use parseInt() to convert (which just accepts your hex string):

parseInt(a);

Then use a mask to figure out if the MSB is set:

a & 0x8000

If that returns a nonzero value, you know it is negative.

To wrap it all up:

a = "0xffeb";
a = parseInt(a, 16);
if ((a & 0x8000) > 0) {
   a = a - 0x10000;
}

Note that this only works for 16-bit integers (short in C). If you have a 32-bit integer, you'll need a different mask and subtraction.

于 2012-11-20T07:42:37.680 に答える
17

私はこれを思いついた

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;
}

そして使用法:

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

基本的に、16 進数の変換範囲は 16 進数の長さに依存します。これが私が探していたものです。それが役に立てば幸い。

于 2016-01-08T14:22:05.007 に答える
0

絶対数値を -2^24 から 2^24-1 の範囲の int32 値に変換する必要があったため、この解決策を思いつきましたparseInt(hex, 16)。 2.

function toSignedInt(value, nBytes) { // 0 <= value < 2^nbytes*4, nBytes >= 1, 
  var hexMask = '0x80' + '00'.repeat(nBytes - 1);
  var intMask = parseInt(hexMask, 16);
  if (value >= intMask) {
    value = value - intMask * 2;
  }
  return value;
}

var vals = [       // expected output
  '0x00',          // 0
  '0xFF',          // 255
  '0xFFFFFF',      // 2^24 - 1 = 16777215
  '0x7FFFFFFF',    // 2^31 -1 = 2147483647
  '0x80000000',    // -2^31 = -2147483648
  '0x80000001',    // -2^31 + 1 = -2147483647
  '0xFFFFFFFF',    // -1
];
for (var hex of vals) {
  var num = parseInt(hex, 16);
  var result = toSignedInt(num, 4);
  console.log(hex, num, result);
}

var sampleInput = '0xffeb';
var sampleResult = toSignedInt(parseInt(sampleInput, 16), 2);
console.log(sampleInput, sampleResult); // "0xffeb", -21
于 2021-05-14T08:06:45.387 に答える