Битовые операторы ECMAScript
- Предыдущая страница Унарные операторы
- Следующая страница Логические операторы
Битовые операторы работают на уровне низового уровня чисел (то есть на 32 разрядах, представляющих число).
Пересмотрим целые числа
В ECMAScript есть два типа целых чисел: целые числа с знаками (разрешены как положительные, так и отрицательные числа) и целые числа без знака (разрешены только положительные числа). В ECMAScript все литералы целых чисел по умолчанию целые числа с знаками, что означает?
Двоичные числа с знаками используют 31 разряд для представления значения числа, 32-й разряд используется для представления знака числа, 0 означает положительное число, 1 означает отрицательное. Диапазон значений варьируется от -2147483648 до 2147483647.
Двоичные числа с знаками можно хранить двумя способами: один для хранения положительных чисел, другой для хранения отрицательных. Положительные числа хранятся в виде истинного двоичного формата, каждый разряд из 31 из которых代表着 степень 2, начиная с первого разряда (разряд 0),代表着 20Второй разряд (разряд 1) означает 21. Неиспользуемые разряды заполняются нулями, то есть они не учитываются. Например, на рисунке показано представление числа 18.

Версия числа 18 в двоичном формате использует только первые 5 разрядов, это и есть эффективные разряды этого числа. Преобразовав число в двоичную строку, можно увидеть эффективные разряды:
var iNum = 18; alert(iNum.toString(2)); // Выводит "10010"
Этот код выводит только "10010", а не 32-битное представление числа 18. Другие разряды не важны, так как для определения этой десятичной величины достаточно первых 5 разрядов. Как показано на рисунке:

Отрицательные числа также хранятся в виде двоичного кода, но в виде двоичного дополнения. Шаги для вычисления двоичного дополнения числа включают в себя три шага:
- Определите двоичное представление неявного版本的 этого числа (например, чтобы вычислить двоичное дополнение -18, сначала необходимо определить двоичное представление 18)
- Получите двоичный обратный код, заменив 0 на 1 и 1 на 0
- Добавьте 1 к двоичному обратному коду
Чтобы определить двоичное представление -18, сначала необходимо получить двоичное представление 18, как показано ниже:
0000 0000 0000 0000 0000 0000 0001 0010
Рассчитайте двоичный обратный код, как показано ниже:
1111 1111 1111 1111 1111 1111 1110 1101
В конце концов, добавьте 1 к двоичному обратному коду, как показано ниже:
1111 1111 1111 1111 1111 1111 1110 1101 1 --------------------------------------- 1111 1111 1111 1111 1111 1111 1110 1110
Таким образом, двоичное представление -18 равно 1111 1111 1111 1111 1111 1111 1110 1110. Запомните, при обработке знаковых целых чисел разработчики не могут получить доступ к 31-му биту.
Интересно, что ECMAScript не показывает отрицательные числа в виде двоичного дополнения после их преобразования в двоичную строку, а выводит их в виде стандартного двоичного кода абсолютной величины числа с добавлением знака минус. Например:
var iNum = -18; alert(iNum.toString(2)); // Вывод "-10010"
Этот код выводит "-10010", а не двоичное дополнение, чтобы избежать доступа к биту 31. Для удобства ECMAScript обрабатывает целые числа простым способом, чтобы разработчики не беспокоились о их использовании.
С другой стороны, незнаковые целые числа рассматривают последний бит как еще один разряд. В этом режиме 32-й бит не представляет знак числа, а равноценен значению 231Из-за этой дополнительной бита диапазон значений незнаковых целых чисел составляет от 0 до 4294967295. Для чисел, меньших 2147483647, незнаковые целые числа выглядят так же, как и знаковые целые числа, а для чисел, больших 2147483647, необходимо использовать бит 31 (в знаковых целых числах этот бит всегда равен 0).
Преобразование незнаковых целых чисел в строку возвращает только их эффективные биты.
Внимание:Все целочисленные литералы по умолчанию хранятся как знаковые целые числа. Только операторы битов ECMAScript могут создавать незнаковые целые числа.
Операции с битами NOT
Операции с битами NOT представляются символом отрицания (~), это один из немногих операторов, связанных с двоичной арифметикой в ECMAScript.
Битовое вычисление NOT является трехшаговым процессом:
- Преобразование операнда в 32-битное число
- Преобразование двоичного числа в его двоичное дополнение
- Преобразование двоичного числа в浮инговое число
Например:
var iNum1 = 25; //25 равно 00000000000000000000000000011001 var iNum2 = ~iNum1; //Преобразование в двоичное дополнение alert(iNum2); //вывод "-26"
Битовое вычисление NOT по сути является обратным числом, вычтенным из числа, и затем уменьшенным на 1, поэтому 25 становится -26. Получение такого же результата можно также получить следующим образом:
var iNum1 = 25; var iNum2 = -iNum1 -1; alert(iNum2); //вывод -26
Битовое вычисление AND
Битовое вычисление AND обозначается символом (&) и напрямую выполняется над двоичным представлением чисел. Он выравнивает разряды каждого числа и выполняет AND операцию над двумя числами в одном и том же разряде по следующим правилам:
Разряды первого числа | Разряды второго числа | Результат |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
Например, чтобы выполнить AND операцию над числами 25 и 3, код будет выглядеть так:
var iResult = 25 & 3; alert(iResult); //вывод "1"
Результат AND операции 25 и 3 равен 1. Почему? Анализ如下:
25 = 0000 0000 0000 0000 0000 0000 0001 1001 3 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- AND = 0000 0000 0000 0000 0000 0000 0000 0001
可以看出, в 25 и 3只有一个 разряд (разряд 0) содержит 1, поэтому другие разряды генерируют 0, поэтому результат равен 1.
Битовое вычисление OR
Битовое вычисление OR обозначается символом (|) и напрямую выполняется над двоичным представлением чисел. При вычислении каждого разряда, оператор OR использует следующие правила:
Разряды первого числа | Разряды второго числа | Результат |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
Пример использования оператора AND, чтобы выполнить OR операцию 25 и 3, код如下所示:
var iResult = 25 | 3; alert(iResult); //вывод "27"
Результат OR операции 25 и 3 равен 27:
25 = 0000 0000 0000 0000 0000 0000 0001 1001 3 = 0000 0000 0000 0000 0000 0000 0000 0011 -------------------------------------------- OR = 0000 0000 0000 0000 0000 0000 0001 1011
可以看出,в двух числах共有 4 числовых места, содержащих 1, эти места передаются в результат. Двоичный код 11011 равен 27.
Битовая операция XOR
Битовая операция XOR представлена символом (^), конечно, также выполняется напрямую на двоичном формате. XOR отличается от OR, он возвращает 1 только тогда, когда один разряд содержит 1. Таблица истинности такова:
Разряды первого числа | Разряды второго числа | Результат |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
Для XOR-операции 25 и 3 код выглядит следующим образом:
var iResult = 25 ^ 3; alert(iResult); // вывод "26"
Результат XOR-операции 25 и 3 равен 26:
25 = 0000 0000 0000 0000 0000 0000 0001 1001 3 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- XOR = 0000 0000 0000 0000 0000 0000 0001 1010
可以看出, в двух числах есть 4 разряда, содержащих 1, эти разряды передаются в результат. Двоичный код 11010 равен 26.
Оператор левого сдвига
Оператор левого сдвига представлен двумя меньшеюшими знаками (<<). Он сдвигает все разряды числа влево на указанное количество. Например, если сдвинуть число 2 (равное двоичному 10) влево на 5 разрядов, результат будет 64 (равное двоичному 1000000):
var iOld = 2; // равно двоичному 10 var iNew = iOld << 5; // равно двоичному 1000000 десятичному 64
Внимание:При левых сдвигах в числе образуются 5 пустых мест справа. Оператор левого сдвига заполняет эти места нулями, чтобы результат был полным 32-битным числом.

Внимание:Оператор левого сдвига сохраняет бит знака числа. Например, если сдвинуть -2 влево на 5 разрядов, результат будет -64, а не 64. "Сохраняется ли бит знака в 32-м разряде?" Да, но это выполняется на уровне ECMAScript, и разработчики не могут напрямую обращаться к 32-му разряду. Даже если выводить отрицательное число в виде строки的二进制ного числа, отображается также минус (например, -2 будет отображаться как -10).
Оператор знакового правого сдвига
Оператор знакового правого сдвига представлен двумя большеюшими знаками (>>). Он сдвигает все разряды 32-битного числа вправо, сохраняя при этом знак числа (плюс или минус). Оператор знакового правого сдвига является противоположным по отношению к левому сдвигу. Например, если сдвинуть 64 вправо на 5 разрядов, результат будет 2:
var iOld = 64; // равно двоичному 1000000 var iNew = iOld >> 5; // равно двоичному 10 десятичному 2
Таким же образом, после сдвига разрядов образуются пустые места. В этот раз пустые места находятся слева от числа, но после знакового разряда. ECMAScript заполняет эти пустые места значением знакового разряда, создавая полный номер, как показано на рисунке ниже:

Беззнаковый правый сдвиг
Оператор беззнакового правого сдвига представлен тремя символами больше (>>>), он сдвигает все разряды беззнакового 32-битного числа вправо. Для положительных чисел результат беззнакового правого сдвига такой же, как и знаковый правый сдвиг.
С помощью примера знакового правого сдвига, если сдвинуть 64 вправо на 5 позиций, он станет 2:
var iOld = 64; // равно двоичному 1000000 var iNew = iOld >>> 5; // равно двоичному 10 десятичному 2
Для отрицательных чисел ситуация иная.
Беззнаковый правый сдвиг заполняет все пустые места нулями. Для положительных чисел это аналогично операции знакового правого сдвига, а для отрицательных чисел они обрабатываются как положительные.
Результат беззнакового правого сдвига - это 32-битное положительное число, поэтому беззнаковый правый сдвиг отрицательного числа всегда приводит к очень большому числу. Например, если сдвинуть -64 вправо на 5 позиций, получится 134217726. Как получить такой результат?
Чтобы это сделать, нужно преобразовать этот номер в его беззнаковую эквивалентную форму (хотя сам номер все еще знаковый), которую можно получить следующим образом:
var iUnsigned64 = -64 >>> 0;
Затем, с помощью метода toString() типа Number, получите его истинное двоичное представление,采用的 база - 2:
alert(iUnsigned64.toString(2));
Это генерирует 11111111111111111111111111000000, что является двоичным представлением кода補码 для целого числа -64, но оно равно беззнаковому целому числу 4294967232.
Из-за этой причины использование оператора беззнакового правого сдвига требует осторожности.
- Предыдущая страница Унарные операторы
- Следующая страница Логические операторы