Я пытаюсь записать функцию для возврата числа битов положительное целое число меньше, которое предел 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
Спасибо.
Вы можете сделать:
function bitSize(num) {
return num.toString(2).length;
}
Метод toString()
метода Number
принимает радикс в качестве необязательного аргумента.
Вот некоторые тесты. Работает в Chrome, Safari, Opera и Firefox. Доступа к IE нет, извините.
Побитовые операции будут надежно работать в 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, длину которых можно просто взять.
Создайте таблицу поиска с соответствующими границами, в которых изменяются биты. Вы можете сделать это только для больших значений и по-прежнему делать меньшие с помощью логарифма. Похоже, что это вообще связано с плавающей запятой, так как я могу воспроизвести это в PowerShell и здесь.