Why does std::bit_width return 0 for the value 0, shouldn’t it return 1?

There is a strange bit of history to bit_width.

The function that would eventually become known as bit_width started life as log2, as part of a proposal adding integer power-of-two functions. log2 was specified to produce UB when passed 0.

Because that’s how logarithms work.

But then, things changed. The function later became log2p1, and for reasons that are not specified was given a wider contract (“wide contract” in C++ parlance means that more stuff is considered valid input). Specifically, 0 is valid input, and yields the value of 0.

Which is not how logarithms work, but whatever.

As C++20 neared standardization, a name conflict was discovered (PDF). The name log2p1 happens to correspond to the name of an IEEE-754 algorithm, but it’s a radically different one. Also, functions in other languages with similar inputs and results use a name like bit_length. So it was renamed to bit_width.

And since it’s not pretending to do a logarithm anymore, the behavior at 0 can be whatever we want.

Indeed, the Python function int.bit_length has the exact same behavior. Leading zeros are not considered part of the bit length, and since a value of 0 contains all leading zeros…

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)