Обсуждение: Bit count

Поиск
Список
Период
Сортировка

Bit count

От
Nathaniel Trellice
Дата:
I'd like to use an integer column (16 bits will suffice) to hold a bit-field. I'd like to be able to efficiently count
thenumber of bits set in this field. 

Is there a built-in function call I can use? (I can't find one in the manual).

If not, can anyone recommend the most efficient way within postgres to implement the kind of bit-counting tricks found
at:

http://gurmeetsingh.wordpress.com/2008/08/05/fast-bit-counting-routines/
http://graphics.stanford.edu/~seander/bithacks.html

Nathaniel





Re: Bit count

От
Rikard Bosnjakovic
Дата:
On Tue, Nov 24, 2009 at 16:47, Nathaniel Trellice <naptrel@yahoo.co.uk> wrote:

[...]
> If not, can anyone recommend the most efficient way within postgres to implement the kind of bit-counting tricks
foundat: 

Perhaps something like this:

CREATE OR REPLACE FUNCTION bitcount(i integer) RETURNS integer AS $$
DECLARE n integer;
DECLARE amount integer;
  BEGIN
    amount := 0;
    FOR n IN 1..16 LOOP
      amount := amount + ((i >> (n-1)) & 1);
    END LOOP;
    RETURN amount;
  END
$$ LANGUAGE plpgsql;


bos=# select bitcount(6);
 bitcount
----------
        2
(1 row)

bos=# select bitcount(7);
 bitcount
----------
        3

bos=# select bitcount(4711);
 bitcount
----------
        7
(1 row)

bos=# select bitcount(1024);
 bitcount
----------
        1
(1 row)


--
- Rikard

Re: Bit count

От
Kenneth Marshall
Дата:
On Tue, Nov 24, 2009 at 07:18:00PM +0100, Rikard Bosnjakovic wrote:
> On Tue, Nov 24, 2009 at 16:47, Nathaniel Trellice <naptrel@yahoo.co.uk> wrote:
>
> [...]
> > If not, can anyone recommend the most efficient way within postgres to implement the kind of bit-counting tricks
foundat: 
>
> Perhaps something like this:
>
> CREATE OR REPLACE FUNCTION bitcount(i integer) RETURNS integer AS $$
> DECLARE n integer;
> DECLARE amount integer;
>   BEGIN
>     amount := 0;
>     FOR n IN 1..16 LOOP
>       amount := amount + ((i >> (n-1)) & 1);
>     END LOOP;
>     RETURN amount;
>   END
> $$ LANGUAGE plpgsql;
>
>
> bos=# select bitcount(6);
>  bitcount
> ----------
>         2
> (1 row)
>
> bos=# select bitcount(7);
>  bitcount
> ----------
>         3
>
> bos=# select bitcount(4711);
>  bitcount
> ----------
>         7
> (1 row)
>
> bos=# select bitcount(1024);
>  bitcount
> ----------
>         1
> (1 row)
>
>
> --
> - Rikard
>

You could also setup a lookup table and just select the
bit count from the table. There was also a thread on how
to efficiently count the set bits that concluded with the
posting of a C function that could be used. It all depends
on your need for speed.

Regards,
Ken

Re: Bit count

От
Josh Kupershmidt
Дата:
On Tue, Nov 24, 2009 at 1:18 PM, Rikard Bosnjakovic
<rikard.bosnjakovic@gmail.com> wrote:
> On Tue, Nov 24, 2009 at 16:47, Nathaniel Trellice <naptrel@yahoo.co.uk> wrote:
>
> [...]
>> If not, can anyone recommend the most efficient way within postgres to implement the kind of bit-counting tricks
foundat: 
>
> Perhaps something like this:
>
> CREATE OR REPLACE FUNCTION bitcount(i integer) RETURNS integer AS $$
> DECLARE n integer;
> DECLARE amount integer;
>  BEGIN
>    amount := 0;
>    FOR n IN 1..16 LOOP
>      amount := amount + ((i >> (n-1)) & 1);
>    END LOOP;
>    RETURN amount;
>  END
> $$ LANGUAGE plpgsql;
>

[snip]
Clever! Here's a pure SQL version I whipped up.. perhaps there's a
more efficient pure SQL way that can avoid the string operations I'm
using :-)

# SELECT num, char_length(replace(num::bit(16)::text, '0', '')) AS
num_set_bits FROM numbers;
 num  | num_set_bits
------+--------------
    6     |            2
    7     |            3
 4711  |            7
 1024  |            1

Josh

Re: Bit count

От
Jasen Betts
Дата:
On 2009-11-24, Nathaniel Trellice <naptrel@yahoo.co.uk> wrote:
> I'd like to use an integer column (16 bits will suffice) to hold a bit-field. I'd like to be able to efficiently
countthe number of bits set in this field. 
>
> Is there a built-in function call I can use? (I can't find one in the manual).

convert it to a text representation of the binary value use regexp_replace to remove the 0s take the length.

> If not, can anyone recommend the most efficient way within postgres to implement the kind of bit-counting tricks
foundat: 

postgres functions can be written in C (if you have superuser
priviledges) seems like overkill though.


Re: Bit count

От
Nathaniel Trellice
Дата:
Thanks for all the replies.

I'm giving this a spin, at present. It's based on Rikard's suggestion of using plpgsql script function. Like Jason and
otherhave said, it could be done in a C function (and this was my first inclination), but the hassle of worrying about
linkinglibraries, 32/64-bit installation etc is probably overkill. So this implementation of the 'MIT Hakmem' algorithm
seemedlike a good compromise between efficiency and efficacy: 

CREATE FUNCTION mybitcount(n int4) RETURNS int4 AS $$
  DECLARE tmp int4;
  BEGIN
    tmp = n - ((n >> 1) & 3681400539) - ((n >> 2) & 1227133513);
    RETURN ((tmp + (tmp >> 3)) & 3340530119) % 63;
  END
$$ LANGUAGE plpgsql IMMUTABLE STRICT;


Nathaniel