سؤال

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.

هل كانت مفيدة؟

المحلول

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.

http://jsfiddle.net/MTj63/

As a side note, I think your fromOctal() function should actually be named fromBinary().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top