From c756ea14ed1f4258bfc17612362bf0020037db39 Mon Sep 17 00:00:00 2001 From: Monmohan Date: Sat, 23 Nov 2013 15:41:39 +0530 Subject: [PATCH] BitSet.cardinality() - courtesy Hacker's Delight --- lib/BitSet.js | 19 +++++++++++++++++++ tests/TestBitSet.js | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/BitSet.js b/lib/BitSet.js index 9b53fed..777674c 100644 --- a/lib/BitSet.js +++ b/lib/BitSet.js @@ -42,6 +42,25 @@ }; + /** + * Return the number of bits set to true in this + * BitSet + * Courtesy Hacker's Delight 5.1 + */ + BitSet.prototype.cardinality = function () { + return this._words.reduce(function (sum, w) { + w = w - ((w >>> 1) & 0x55555555); + w = (w & 0x33333333) + ((w >>> 2) & 0x33333333); + w = (w + (w >>> 4)) & 0x0f0f0f0f; + w = w + (w >>> 8); + w = w + (w >>> 16); + return sum + (w & 0x3F); + + }, 0); + + }; + + BitSet.prototype.size = function () { return this._wordsUsed * BITS_PER_WORD; }; diff --git a/tests/TestBitSet.js b/tests/TestBitSet.js index 8c6e7e7..34589e6 100644 --- a/tests/TestBitSet.js +++ b/tests/TestBitSet.js @@ -39,8 +39,27 @@ var BitSet = require('../lib/BitSet.js'), assert = require('assert'), fs = requi } + function testCardinality() { + var bs = new BitSet(); + bs.set(10); + bs.set(2); + assert.equal(bs.cardinality(), 2, 'wrong cardinality'); + bs = new BitSet(1000); + for (var i = 0; i < 20; i++) { + bs.set(i * 10); + } + assert.equal(bs.cardinality(), 20, 'wrong cardinality'); + //clear a few + for (i = 0; i < 20; i++) { + bs.clear(i * 20); + } + assert.equal(bs.cardinality(), 10, 'wrong cardinality'); + + } + testBasic(); testLargeBitSet(); + testCardinality(); })(); \ No newline at end of file