英文:
Endianness issue with Javascript bitwise shift left
问题
我正在尝试将这个简单的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]
。
我在哪里出错了?我认为可能与字节序有关,但我不知道如何一致地处理这种问题。
英文:
I am trying to translate this simple function from Go to 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
}
My first attempt was this:
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;
}
However, this does not work. Given the following test case:
function fromOctal(str) {
var bytes = [parseInt(str, 2)];
return bytes;
}
console.log(shiftLeft(fromOctal("10000000"))
The Javascript version returns [256]
, but the expected result is "00000000" or [0]
.
What am I getting wrong here? I think it might have to do with endianness, but I have no idea about how to deal with this kind of issue consistently.
答案1
得分: 2
你的错误在于假设数组的元素是8位整数,但是在JavaScript中,位运算符的结果是32位整数,因此当你进行左移操作时,最高位仍然保留。
我认为通过修改以下代码:
output[i] = b[i] << 1;
为:
output[i] = (b[i] << 1) & 0xFF;
可以解决你的问题。
另外,我认为你的fromOctal()
函数实际上应该被命名为fromBinary()
。
英文:
Your mistake appears to be in assuming that the elements of your array are 8-bit integers, but the result of bitwise operators in JavaScript are 32-bit integers and so the most significant bit remains when you do the left shift.
I believe that adding a bit mask by changing:
output[i] = b[i] << 1;
to:
output[i] = (b[i] << 1) & 0xFF;
should fix your issue.
As a side note, I think your fromOctal()
function should actually be named fromBinary()
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论