11defmodule Abit.Bitmask do
22 @ moduledoc """
33 Functions for working with bits and integer bitmasks.
4+
5+ `set_bits_count/1` and `hamming_distance/2` treat integers as 64-bit
6+ bitmasks: they inspect bits 0 through 63 and ignore higher bits. Negative
7+ integers are interpreted using their lowest 64 two's-complement bits.
8+
9+ The indexed operations are not capped at 64 bits, and `to_list/2` uses the
10+ explicit size supplied by the caller.
411 """
512
613 import Bitwise
714
815 @ doc """
916 Returns the count of bits set to 1 in the given integer `int`.
1017
18+ Only the lowest 64 bits are counted. Bits above bit 63 are ignored, and
19+ negative integers are interpreted using their lowest 64 two's-complement
20+ bits.
21+
1122 ## Examples
1223
1324 iex> Abit.Bitmask.set_bits_count(3)
@@ -19,21 +30,22 @@ defmodule Abit.Bitmask do
1930 iex> Abit.Bitmask.set_bits_count(1023)
2031 10
2132 """
22- @ popcount_table ( for i <- 0 .. 255 ,
23- do:
24- for ( << b :: 1 <- << i :: 8 >> >> , b == 1 , reduce: 0 , do: ( acc -> acc + 1 ) ) )
33+ @ popcount_table for (
34+ i <- 0 .. 255 ,
35+ do: for ( << ( b :: 1 <- << i :: 8 >> ) >> , b == 1 , reduce: 0 , do: ( acc -> acc + 1 ) )
36+ )
2537 |> List . to_tuple ( )
2638
2739 @ spec set_bits_count ( integer ) :: non_neg_integer
2840 def set_bits_count ( int ) when is_integer ( int ) do
2941 elem ( @ popcount_table , int &&& 255 ) +
30- elem ( @ popcount_table , ( int >>> 8 ) &&& 255 ) +
31- elem ( @ popcount_table , ( int >>> 16 ) &&& 255 ) +
32- elem ( @ popcount_table , ( int >>> 24 ) &&& 255 ) +
33- elem ( @ popcount_table , ( int >>> 32 ) &&& 255 ) +
34- elem ( @ popcount_table , ( int >>> 40 ) &&& 255 ) +
35- elem ( @ popcount_table , ( int >>> 48 ) &&& 255 ) +
36- elem ( @ popcount_table , ( int >>> 56 ) &&& 255 )
42+ elem ( @ popcount_table , int >>> 8 &&& 255 ) +
43+ elem ( @ popcount_table , int >>> 16 &&& 255 ) +
44+ elem ( @ popcount_table , int >>> 24 &&& 255 ) +
45+ elem ( @ popcount_table , int >>> 32 &&& 255 ) +
46+ elem ( @ popcount_table , int >>> 40 &&& 255 ) +
47+ elem ( @ popcount_table , int >>> 48 &&& 255 ) +
48+ elem ( @ popcount_table , int >>> 56 &&& 255 )
3749 end
3850
3951 @ doc """
@@ -101,6 +113,10 @@ defmodule Abit.Bitmask do
101113 Returns the bitwise Hamming distance between the
102114 given integers `int_l` and `int_r`.
103115
116+ The distance covers only the lowest 64 bits. Bits above bit 63 are ignored,
117+ and negative integers are interpreted using their lowest 64
118+ two's-complement bits.
119+
104120 ## Examples
105121
106122 iex> Abit.Bitmask.hamming_distance(1, 1)
0 commit comments