Hamming weight/population count in T-SQL

前端 未结 4 898
栀梦
栀梦 2020-12-12 01:41

I\'m looking for a fast way to calculate the hamming weight/population count/\"the number of 1 bits\" of a BINARY(1024) field. MySQL has a BIT_COUNT functio

4条回答
  •  盖世英雄少女心
    2020-12-12 02:38

    You could use a helper table with precalculated Hamming weights for small numbers, like bytes, then split the value accordingly, join to the helper table and get the sum of partial Hamming weights as the value's Hamming weight:

    -- define Hamming weight helper table
    DECLARE @hwtally TABLE (byte tinyint, hw int);
    INSERT INTO @hwtally (byte, hw) VALUES (0, 0);
    INSERT INTO @hwtally (byte, hw) SELECT   1 - byte, 1 - hw FROM @hwtally;
    INSERT INTO @hwtally (byte, hw) SELECT   3 - byte, 2 - hw FROM @hwtally;
    INSERT INTO @hwtally (byte, hw) SELECT   7 - byte, 3 - hw FROM @hwtally;
    INSERT INTO @hwtally (byte, hw) SELECT  15 - byte, 4 - hw FROM @hwtally;
    INSERT INTO @hwtally (byte, hw) SELECT  31 - byte, 5 - hw FROM @hwtally;
    INSERT INTO @hwtally (byte, hw) SELECT  63 - byte, 6 - hw FROM @hwtally;
    INSERT INTO @hwtally (byte, hw) SELECT 127 - byte, 7 - hw FROM @hwtally;
    INSERT INTO @hwtally (byte, hw) SELECT 255 - byte, 8 - hw FROM @hwtally;
    
    -- calculate
    WITH split AS (
      SELECT SUBSTRING(@value, number, 1) AS byte
      FROM master.dbo.spt_values
      WHERE type = 'P' AND number BETWEEN 1 AND LEN(@value)
    )
    SELECT
      Value = @value,
      HammingWeight = SUM(t.hw)
    FROM split s
      INNER JOIN @hwtally t ON s.byte = t.byte
    

提交回复
热议问题