Как я мог посчитать бит из большого числа в JavaScript? - PullRequest
2 голосов
/ 02 июня 2019

У меня в строке хранится большое число.

let txt = '10000000000000041';

Итак, как мне считать бит, представленный в двоичном формате.например, двоичный формат 9 равен 1001, а номер 1 не равен 2.

Что я сделал до сих пор:

const countOne = (num) => {
  let c = 0;
  while (num > 0) {
    num &= num - 1;
    c++;
  }
  return c;
}

console.log(countOne(+'9'));
console.log(countOne(+'10000000000000041'));

Этот код работает нормально, но не для большого значения, потому что Number в JavaScript не может содержать такое большое значение, поэтому он дает неправильный ответ.

Я нашел похожие вопросы, но не для большого значения.

Ответы [ 2 ]

2 голосов
/ 02 июня 2019

В более новых движках (по крайней мере, Chrome, FF, Opera и Node, см. таблица совместимости ), просто приведите к BigInt сначала:

let txt='10000000000000041';
const countOne = (num) => {
  let c = 0;
  while (num > 0) {
    num &= num - 1n;
    c++;
  }
  return c;
}
console.log(countOne(BigInt(txt)));
console.log(countOne(BigInt(1)));
console.log(countOne(BigInt(2)));
console.log(countOne(BigInt(3)));
console.log(countOne(BigInt(4)));
console.log(countOne(BigInt(5)));
console.log(countOne(BigInt(6)));
console.log(countOne(BigInt(7)));
<script>
try {
  eval('1n');
} catch(e) {
  throw "Your browser doesn't support BigInt syntax yet";
}
</script>

10000000000000041 в двоичном формате равно 100011100001101111001001101111110000010000000000101001, поэтому 23 является правильным:

console.log(
  [...'100011100001101111001001101111110000010000000000101001']
  .reduce((a, b) => a + (b === '1'), 0)
);
1 голос
/ 02 июня 2019

Для тех, у кого нет BigInt, вот решение для преобразования в двоичное с помощью евклидова деления:

let txt ='10000000000000041'
,   bin = GetBinary(txt)
;
console.log('Base 10 = ', txt )
console.log('Base 2  = ', bin )
console.log('number of digits on 1 = ', bin.replace(/0/g,'').length )

function GetBinary(strNum)
{
  let Bin = ''
  ,   val = strNum
  ,   Rep = null
  ;
  for(let l=0;l<200;l++)  // loop limitation to 200 by security
  {
    Rep = Div_2(val)
    val = Rep.R
    Bin = Rep.D + Bin
    if (val==='') break;
  } 
  if (val!=='') console.log( 'too much loops for conversion')
  return Bin
}

function Div_2(sNum)
{
  let D = R = ''                 // dividande, results
  ,   d = x = r = 0             // temp vals
  ;
  for(let p=0;p<sNum.length;p++)
  {
    D += sNum.charAt(p)
    d = parseInt(D,10)
    if ( d < 2 ) R += '0'
    else
    {
      x = Math.trunc(d / 2)
      r = d % 2
      D = r.toString(10)
      R += x.toString(10)
    }
  }
  R = R.replace(/\b0+/g, '')     // remove leading zeros
  D = parseInt(D,10).toString() // .except the last one
  return { R, D }
}

[править = исправлены незначительные ошибки + информация]

информация: максимальное количество полезных циклов (в GetBinary () ), равно
Math.ceil(Math.log2(Math.pow(10,n)))
, где n - количество цифр в базе 10.
Здесь приведены «объяснения»:
Существует ли формула для расчета или оценкиколичество цифр двоичного целого числа?

(спасибо Jaromanda X )

...