Tinkering
Come for the Foo, stay for the Bar


Bitmask tables

Posted on

Table of Contents:

At $WORK I have a need to create some bitmasks over a 64-bit field. I've never done this before. I figured that surely tables exist for grabbing a certain number of bits from a certain position, but I never found those tables. So, to scratch my own itch I wrote a very simple Python program to generate the tables and used a CSV to Markdown converter to create the tables. Here you go, now we both have a quick reference.

Update 2023-04-04: Someone on Mastodon mentioned bitwise, an interactive terminal program for bit manipulations. It looks pretty cool!

Program

bit_sizes = [1, 8, 16, 32]
total_bits = 64

for bit_size in bit_sizes:
    positions = int(total_bits / bit_size)
    n = 0
    for _ in range(bit_size):
        n = n << 1
        n += 1
    print(f"# {bit_size} bits")
    for pos in range(positions):
        print(f"{pos}, {n}")
        n = n << bit_size

Table format

Each table has a "position" column and a "decimal value" column. The "position" refers to which n bits you're setting to 1. For a single bit the position is which individual bit is 1. For 8 bits the position is which 8 bits you're setting to 1. The decimal value is the decimal value when the bits at the given position are set to 1. For example, 8 bits in position 1 (the second byte) corresponds to the binary number 0b000....01111111100000000 and the decimal value 65280.

To get the mask for an odd number of bits you can just add the decimal values in the table since the positions don't overlap for a given number of bits.

1 bit

PositionDecimal Value
01
12
24
38
416
532
664
7128
8256
9512
101024
112048
124096
138192
1416384
1532768
1665536
17131072
18262144
19524288
201048576
212097152
224194304
238388608
2416777216
2533554432
2667108864
27134217728
28268435456
29536870912
301073741824
312147483648
324294967296
338589934592
3417179869184
3534359738368
3668719476736
37137438953472
38274877906944
39549755813888
401099511627776
412199023255552
424398046511104
438796093022208
4417592186044416
4535184372088832
4670368744177664
47140737488355328
48281474976710656
49562949953421312
501125899906842624
512251799813685248
524503599627370496
539007199254740992
5418014398509481984
5536028797018963968
5672057594037927936
57144115188075855872
58288230376151711744
59576460752303423488
601152921504606846976
612305843009213693952
624611686018427387904
639223372036854775808

8 Bits

PositionDecimal Value
0255
165280
216711680
34278190080
41095216660480
5280375465082880
671776119061217280
718374686479671623680

16 bits

PositionDecimal Value
065535
14294901760
2281470681743360
318446462598732840960

32 bits

PositionDecimal Value
04294967295
118446744069414584320

P.S. - You can follow me on Mastodon at @zmitchell for Rust, Nix, and lukewarm takes.

P.P.S. - If you notice that something could be more accessible, please reach out and I'll do my best to fix it!