Целочислено деление и битово изместване в JavaScript

Извършва кода на JavaScript

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

винаги означава "цяло число деление на 2 без остатък"? Притеснението ми е endiance, ако целочисленият литерал е по-голям от един байт.

Предисторията на въпроса ми е следната:

Имам целочислена променлива в диапазона от 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;
}

Този код работи в моя браузър, но се чудя дали ще работи навсякъде. Основната идея е попълването на масива чрез вземане на LSB и разделяне на 256. Но реално деление "/" би превърнало променливата в променлива с плаваща запетая. Така че използвам ">>8", но това всъщност предполага голямо разпределение.


person user2690527    schedule 16.08.2013    source източник
comment
Този код работи в моя браузър, но се чудя дали ще работи навсякъде. Имате предвид на други езици? Или искате да потвърдите, че x >> y прехвърля x към (подписан) Int32. Той също така запазва най-левите битове (те не стават 0, което би се случило, ако използвате >>>).   -  person Paul S.    schedule 17.08.2013
comment
С навсякъде исках да кажа във всеки браузър на всяка машина. Всичките ми компютри са съвместими с Intel, така че не мога да потвърдя какво ще се случи на устройства с голям endianness.   -  person user2690527    schedule 17.08.2013


Отговори (1)


Кодът, който сте дали, няма абсолютно никакво отношение към endianess.

Въпреки това, ако преинтерпретирате масива от байтове в да речем масив uint32, тогава резултатът ще бъде различен в зависимост от endiance на машината, на която работи браузърът.

Първо поправете грешката в кода:

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]` е това, което се надявах да чуя, въпреки че не разбирам защо казвате, че endiance е без значение. - person user2690527; 17.08.2013
comment
@user2690527, защото е - винаги е един и същ резултат за това, независимо от endiance, следователно endiance не е уместно - 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 смяната не се извършва в паметта, но първо се зарежда от паметта в регистър на процесора (където endiance е без значение, тъй като не можете да адресирате регистъра в байтове). Следователно ще има същия логичен резултат (62). След това самото число 62 се съхранява в паметта във формат, зависим от endiness. - person Esailija; 17.08.2013
comment
@user2690527 Намерих някои статии за вас, за да можете да разберете кога endianess има значение en.wikipedia.org/wiki/ Endianess cs.umd.edu/class /sum2003/cmsc311/Notes/Data/endian.html - person Esailija; 17.08.2013