Число битов для представления числа

Я пытаюсь записать функцию для возврата числа битов положительное целое число меньше, которое предел JavaScript (2^53)-1. Однако я поражаюсь проблемами точности и хочу избежать крупных целочисленных библиотек.

Метод 1:

function bitSize(num)
{
return Math.floor( Math.log(num) / Math.log(2) ) + 1;
}

Pass: bitSize( Math.pow(2, 16) -1 ) = 16
Pass: bitSize( Math.pow(2, 16) ) = 17
Fail (Should be 48): bitSize( Math.pow(2, 48) -1 ) = 49 
Pass: bitSize( Math.pow(2, 48) ) = 49

Метод 2:

function bitSize(num)
{
var count = 0;
while(num > 0)
{
    num = num >> 1;
    count++;
}
return count;
}

Pass: bitSize( Math.pow(2, 16) -1 ) = 16
Pass: bitSize( Math.pow(2, 16) ) = 17
Fail (Should be 48): bitSize( Math.pow(2, 48) -1 ) = 1
Fail (Should be 49): bitSize( Math.pow(2, 48) ) = 1

Оба метода перестали работать к проблемам точности, я думаю.

Может любой предлагать альтернативный метод, который будет работать на числа между 0-> 2^53-1

Спасибо.

9
задан hippietrail 17 April 2011 в 09:52
поделиться

3 ответа

Вы можете сделать:

function bitSize(num) {
    return num.toString(2).length;
}

Метод toString() метода Number принимает радикс в качестве необязательного аргумента.

Вот некоторые тесты. Работает в Chrome, Safari, Opera и Firefox. Доступа к IE нет, извините.

9
ответ дан 4 December 2019 в 09:12
поделиться

Побитовые операции будут надежно работать в Javascript только для «целых» до 32 бит. Цитата из Полный справочник по номерам JavaScript :

Побитовые операции - это своего рода взлом в Javascript. Поскольку все числа в Javascript - это плавающая точка, а побитовые операторы работают только с целые числа, Javascript немного закулисная магия, чтобы сделать это появляются побитовые операции. применяется к 32-битному целому числу со знаком.

В частности, Javascript принимает номер, над которым вы работаете и занимаетесь целая часть числа. Это затем преобразует целое число в наибольшее количество битов, которое представляет собой число, до 31 бит (1 бит для знака). Так 0 создаст двухбитное число (1 для знак и 1 бит для 0), аналогично 1 создаст два бита.2 создаст 3-битное число, 4 создаст 4-битное число и т. д.

Важно понимать, что вы не гарантируется 32-битное число, для экземпляр, работающий не на нуле, должен, теоретически преобразовать 0 в 4,294,967,295, вместо этого он вернет -1 для двоих причины, во-первых, что все числа подписаны в Javascript, поэтому «не» всегда меняет знак, и второй Javascript не мог сделать больше чем один бит от нуля и не ноль становится единицей. Следовательно, ~ 0 = -1.

Итак, побитовые знаки в Javascript активны до 32 бит.

Как отмечает Анураг, в этой ситуации вам следует просто использовать встроенный num.toString (2) , который выводит строку минимальной длины ASCII '1' s. и '0' s, длину которых можно просто взять.

10
ответ дан 4 December 2019 в 09:12
поделиться

Создайте таблицу поиска с соответствующими границами, в которых изменяются биты. Вы можете сделать это только для больших значений и по-прежнему делать меньшие с помощью логарифма. Похоже, что это вообще связано с плавающей запятой, так как я могу воспроизвести это в PowerShell и здесь.

1
ответ дан 4 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: