Javascript逐位左移的终结性问题

Endianness issue with Javascript bitwise shift left

本文关键字:问题 左移 Javascript      更新时间:2023-09-26

我正在尝试将这个简单的函数从Go转换为Javascript:

func ShiftLeft(b []byte) []byte {
    l := len(b)
    if l == 0 {
        panic("shiftLeft requires a non-empty buffer.")
    }
    output := make([]byte, l)
    overflow := byte(0)
    for i := int(l - 1); i >= 0; i-- {
        output[i] = b[i] << 1
        output[i] |= overflow
        overflow = (b[i] & 0x80) >> 7
    }
    return output
}

我的第一次尝试是:

function makeEmpty(size) {

  var result = [];
  for (var i = 0; i < size; i++) {
    result.push(0x00);
  }
  return result;
}
function shiftLeft (b) {
  var len = b.length;
  if (len == 0) {
    throw 'shiftLeft requires a non-empty buffer';
  }
  var output = makeEmpty(len);
  var overflow = 0;
  for (var i = len - 1; i >= 0; i--) {
    output[i] = b[i] << 1;
    output[i] |= overflow;
    overflow = (b[i] & 0x80) >> 7;
  }
  return output;
}

然而,这是行不通的。给定以下测试用例:

function fromOctal(str) {
  var bytes = [parseInt(str, 2)];
  return bytes;
}
console.log(shiftLeft(fromOctal("10000000"))

Javascript版本返回[256],但预期结果为"00000000"或[0]

我做错了什么?我认为这可能与endianness有关,但我不知道如何始终如一地处理这种问题。

您的错误似乎是假设数组的元素是8位整数,但JavaScript中逐位运算符的结果是32位整数,因此当您进行左移时,最高有效位仍然存在。

我相信通过更改添加一个位掩码:

output[i] = b[i] << 1;

至:

output[i] = (b[i] << 1) & 0xFF;

应该解决您的问题。

http://jsfiddle.net/MTj63/

顺便说一句,我认为fromOctal()函数实际上应该命名为fromBinary()