如何从javascript中的大量数字中计数?

时间:2019-06-01 22:01:27

标签: javascript data-structures bit-manipulation

我有很多存储在字符串中。

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'));

此代码可以正常工作,但不能实现较大的价值,因为JavaScript中的Number无法拥有如此大的价值,因此给出了错误的答案。

我发现了类似的问题,但不是很有价值。

2 个答案:

答案 0 :(得分:2)

在较新的引擎(至少是Chrome,FF,Opera和Node,请参见compatibility table)中,请先将其强制转换为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以二进制is 100011100001101111001001101111110000010000000000101001表示,因此23是正确的:

console.log(
  [...'100011100001101111001001101111110000010000000000101001']
  .reduce((a, b) => a + (b === '1'), 0)
);

答案 1 :(得分:0)

对于没有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(inText)
{
  let Bin = ''
  ,   val = inText
  ,   Rep = null
  ;
  for(let x=0;x<200;x++)  // 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(txt_arg)  //   Euclid Div by 2
{
  let D = R = ''       // dividande, results
  ,   v = x = 0       // temp vals
  ;
  for (let p=0, pMax=txt_arg.length;p<pMax;p++)
  {
    D += txt_arg.charAt(p); 
    v = parseInt(D,10);
    D = D.replace(/\b0+/g, '')  // remove leading zero

    if (v<2) { R += '0' }
    else {
      x = Math.trunc(v/2)
      v -= (x  *2)
      D = v.toString()
      R += x.toString()
    }
  }
  R = R.replace(/\b0+/g, '')  // remove leading zero
  return {  R, D }
}