Целочисленное деление и битовый сдвиг в JavaScript

Код JavaScript

var n = 8; // or some arbitrary integer literal
n >> 1;

всегда обозначают «целочисленное деление на 2 без остатка»? Меня беспокоит порядок байтов, если целочисленный литерал больше одного байта.

Предыстория моего вопроса следующая:

У меня есть целочисленная переменная в диапазоне от 0 до 2^32-1, которая поместилась бы в uint32, если бы у меня был типизированный язык программирования, отличный от JS. Мне нужно преобразовать это в Uint4Array с четырьмя элементами в обратном порядке.

Мой текущий подход к JavaScript:

function uInt32ToLEByteArray( n ) {
  var byteArray = new Uint8Array(4);
    for( var i = 0; i < 4; i++ ) {
      byteArray[i] = n & 255;
      n >> 8;
    }
  return byteArray;
}

Этот код работает в моем браузере, но мне интересно, будет ли он работать везде. Основная идея состоит в том, чтобы заполнить массив, взяв младший бит и разделив его на 256. Но реальное деление "/" преобразует переменную в переменную с плавающей запятой. Поэтому я использую «>>8», но на самом деле это предполагает прямой порядок байтов.


person user2690527    schedule 16.08.2013    source источник
comment
Этот код работает в моем браузере, но мне интересно, будет ли он работать везде. Вы имеете в виду на других языках? Или вы просите подтвердить, что x >> y приводит x к (подписанному) Int32. Он также сохраняет крайние левые биты (они не становятся 0, что произошло бы, если бы вы использовали >>>).   -  person Paul S.    schedule 17.08.2013
comment
Причём везде я хотел сказать в каждом браузере на каждой машине. Все мои компьютеры совместимы с Intel, поэтому я не могу подтвердить, что произойдет на устройствах с прямым порядком байтов.   -  person user2690527    schedule 17.08.2013


Ответы (1)


Код, который вы дали, не имеет абсолютно никакого отношения к порядку байтов.

Однако, если бы вы переинтерпретировали массив байтов, скажем, в массиве uint32, результат был бы другим в зависимости от порядка байтов машины, на которой работает браузер.

Сначала исправьте ошибку в коде:

function uInt32ToLEByteArray(n) {
    var byteArray = new Uint8Array(4);
    for (var i = 0; i < 4; i++) {
        byteArray[i] = n & 255;
        n >>>= 8; //simply doing n >> 8 has no effect actually
    }
    return byteArray;
}

Затем

var a = uInt32ToLEByteArray(0xFF)
console.log(a);
//always [255, 0, 0, 0]

var b = new Uint32Array(a.buffer);
console.log(b);
//[255] on little endian machines
//[4278190080] on big endian machines
person Esailija    schedule 16.08.2013
comment
Привет. Извините, n >> 8 опечатка. Это очевидно. Вторая часть ваших ответов отвечает на мой вопрос `var a = uInt32ToLEByteArray(0xFF) console.log(a); //всегда [255, 0, 0, 0]` это то, что я надеялся услышать, хотя я не понимаю, почему вы говорите, что порядок байтов не имеет значения. - person user2690527; 17.08.2013
comment
@user2690527 user2690527, потому что это всегда один и тот же результат, независимо от порядка следования байтов, поэтому порядок следования байтов не имеет значения - person Esailija; 17.08.2013
comment
Я подумал, что может быть правдой следующее: Предположим, у нас есть целое число с десятичным значением 992, это 0x03E0 в виде шестнадцатеричного литерала. На машине с прямым порядком байтов это сохраняется как последовательность байтов 0x03,0xE0. Теперь делаем сдвиг вправо на четыре бита (››4). Результат 0x00,0x3E. Возвращаясь к десятичному представлению, это равно 62. Таким образом, ››4 эквивалентно делению на 2^4=16. Теперь мы подошли к моему ложному предположению для машин с прямым порядком байтов. 992 равно 0x03E0 и сохраняется как 0xE0,0x03. Сдвиг на 4 бита дает 0x0E,0x00, что равно 0x000E в виде числового литерала или 14 в виде десятичного числа. - person user2690527; 17.08.2013
comment
@user2690527 user2690527 сдвиг не выполняется в памяти, но сначала загружается из памяти в регистр ЦП (где порядок байтов не имеет значения, поскольку вы не можете адресовать регистр в байтах). Следовательно, это будет иметь тот же логический результат (62). Само число 62 затем сохраняется в памяти в формате, зависящем от порядка байтов. - person Esailija; 17.08.2013
comment
@ user2690527 Я нашел для вас несколько статей, чтобы вы могли понять, когда порядок байтов имеет значение en.wikipedia.org/wiki/ Endianess cs.umd.edu/class /sum2003/cmsc311/Notes/Data/endian.html - person Esailija; 17.08.2013