Math.clz32() считает количество ведущих нулей в 32-битном двоичном представлении числа.
Название можно запомнить так:
clz=count leading zeroes32= работа идёт с 32-битным числом
Это уже не про обычную математику, а про биты и двоичное представление.
Синтаксис
Math.clz32(x)
x - значение, которое будет приведено к беззнаковому 32-битному целому числу.
Что делает Math.clz32()
Метод возвращает, сколько нулей стоит слева в 32-битной двоичной записи числа.
console.log(Math.clz32(1)); // 31
console.log(Math.clz32(2)); // 30
console.log(Math.clz32(1000)); // 22
Это значит:
- у
1только последний бит равен1, поэтому слева31ноль - у
2двоичная запись чуть длиннее, поэтому ведущих нулей уже30 - у
1000ведущих нулей22
Что возвращает Math.clz32()
Math.clz32() возвращает число типа number.
const result = Math.clz32(8);
console.log(result); // 28
console.log(typeof result); // "number"
Результат всегда находится в диапазоне от 0 до 32.
Как это выглядит в двоичной записи
На примере 1 это проще всего увидеть.
// 00000000000000000000000000000001
console.log(Math.clz32(1)); // 31
Слева действительно 31 ноль.
Ещё пример:
// 00000000000000000000001111101000
console.log(Math.clz32(1000)); // 22
У числа 1000 двоичная часть начинается не сразу, поэтому слева остаётся 22 нуля.
Почему Math.clz32(0) равно 32
Это один из самых важных случаев.
console.log(Math.clz32(0)); // 32
У нуля 32-битная двоичная запись выглядит так:
00000000000000000000000000000000
То есть все 32 бита равны нулю.
Результат всегда от 0 до 32
У метода не бывает значений меньше 0 или больше 32.
console.log(Math.clz32(0)); // 32
console.log(Math.clz32(1)); // 31
console.log(Math.clz32(4294967295)); // 0
Полезно помнить:
32означает, что число после преобразования стало00означает, что самый левый бит уже равен1
Значение сначала приводится к 32-битному числу
Это самый важный нюанс при работе с Math.clz32().
Метод не смотрит на исходное число как есть. Сначала он превращает его в беззнаковое 32-битное целое.
Из-за этого некоторые результаты могут удивлять.
Отрицательные числа
Отрицательные значения тоже приводятся к беззнаковому 32-битному формату.
console.log(Math.clz32(-1)); // 0
console.log(Math.clz32(-1000)); // 0
Например, -1 после такого преобразования выглядит как число, у которого все 32 бита равны 1.
// 11111111111111111111111111111111
console.log(Math.clz32(-1)); // 0
Поэтому ведущих нулей здесь нет вообще.
Дробные числа
Дробные значения сначала приводятся к 32-битному целому числу.
console.log(Math.clz32(1.9)); // 31
console.log(Math.clz32(0.5)); // 32
Здесь важно понимать:
1.9после преобразования становится10.5после преобразования становится0
Поэтому и результат получается таким.
Большие числа
Очень большие значения тоже могут вести себя неожиданно, потому что метод работает только с 32 битами.
console.log(Math.clz32(4294967295)); // 0
console.log(Math.clz32(4294967296)); // 32
Во втором случае значение выходит за пределы 32 бит и после преобразования становится 0.
Поэтому результатом будет 32.
Math.clz32() и двоичная длина числа
Math.clz32() удобно использовать, если нужно понять, сколько бит реально занимает число.
Например:
const value = 1000;
const bits = 32 - Math.clz32(value);
console.log(bits); // 10
То есть у числа 1000 значимая двоичная длина равна 10.
Это соответствует и обычной записи:
console.log((1000 >>> 0).toString(2)); // "1111101000"
Math.clz32() и toString(2)
Эти подходы могут использоваться рядом, но делают немного разное.
console.log(Math.clz32(1000)); // 22
console.log((1000 >>> 0).toString(2)); // "1111101000"
Math.clz32()считает нули слева в 32-битной записиtoString(2)показывает само двоичное число без полного 32-битного дополнения
Если вам нужен именно подсчёт ведущих нулей, Math.clz32() удобнее и нагляднее.
Без аргумента
Если вызвать Math.clz32() без аргумента, результатом будет 32.
console.log(Math.clz32()); // 32
Это может показаться неожиданным, но метод попытается обработать undefined, приведёт его к 0 в 32-битном формате и посчитает ведущие нули у нуля.
Неявное приведение типов
Math.clz32() сначала пытается привести аргумент к числу, а потом к 32-битному беззнаковому целому.
console.log(Math.clz32("1")); // 31
console.log(Math.clz32(null)); // 32
console.log(Math.clz32(true)); // 31
console.log(Math.clz32(false)); // 32
На практике лучше передавать в метод уже готовое число.
Массивы и странные значения
Из-за приведения типов некоторые значения могут вести себя неочевидно.
console.log(Math.clz32([])); // 32
console.log(Math.clz32([5])); // 29
console.log(Math.clz32([1, 2])); // 32
Это ещё одна причина, почему лучше не полагаться на неявное преобразование.
NaN и Infinity
Для специальных значений результат будет таким:
console.log(Math.clz32(NaN)); // 32
console.log(Math.clz32(Infinity)); // 32
console.log(Math.clz32(-Infinity)); // 32
Это полезно помнить:
NaNдаёт32Infinityдаёт32-Infinityдаёт32
Причина в том, что после преобразования все эти значения становятся 0 в 32-битном формате.
Число не меняется
Math.clz32() не изменяет исходное значение. Он только возвращает новый результат.
const value = 1000;
const result = Math.clz32(value);
console.log(value); // 1000
console.log(result); // 22
Когда это полезно
Math.clz32() удобно использовать, когда:
- вы работаете с битовыми операциями
- нужно узнать двоичную длину числа
- вы пишете низкоуровневую логику
- нужно быстро анализировать 32-битное представление значения
Пример:
const value = 16;
const leadingZeros = Math.clz32(value);
console.log(leadingZeros); // 27
Частые ошибки
Думать, что метод считает все нули в числе
console.log(Math.clz32(8)); // 28
Метод считает не все нули, а только ведущие нули слева в 32-битной двоичной записи.
Ожидать NaN без аргумента
console.log(Math.clz32()); // 32
Здесь будет не NaN, а 32.
Забывать про преобразование к 32-битному числу
console.log(Math.clz32(1.9)); // 31
console.log(Math.clz32(4294967296)); // 32
Метод работает не с исходным значением как есть, а с его 32-битной версией.
Быстрая памятка
Math.clz32(x)считает ведущие нули в 32-битной двоичной записиclzозначаетcount leading zeroes- метод возвращает
number - результат всегда находится в диапазоне от
0до32 Math.clz32(0)возвращает32Math.clz32(1)возвращает31- перед вычислением значение приводится к беззнаковому 32-битному числу
- отрицательные, дробные и очень большие числа могут давать неожиданный результат
Коротко
Math.clz32() - это стандартный способ посчитать количество ведущих нулей в 32-битном двоичном представлении числа в JavaScript. Главное, что нужно запомнить: метод всегда работает именно с беззнаковым 32-битным значением, поэтому 0 даёт 32, а дробные, отрицательные и слишком большие числа сначала преобразуются перед вычислением.