Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number of value representation bits in a integer, according to the standard?

Consider the following helper structs:

template <class T>
struct bit_count_1:
std::integral_constant<
    std::size_t,
    std::numeric_limits<typename std::make_unsigned<T>::type>::digits
> {};

template <class T>
struct bit_count_2:
std::integral_constant<
    std::size_t,
    std::numeric_limits<T>::digits + std::is_signed<T>::value
> {};

template <class T>
constexpr std::size_t compute_bit_count() {
    using type = typename std::make_unsigned<T>::type;
    constexpr type zero = 0;
    constexpr type one = 1;
    constexpr type max = ~zero;
    type current = max;
    std::size_t i = 0; 
    while (current) {
        current >>= one;
        ++i;
    }
    return i;
}

template <class T>
struct bit_count_3:
std::integral_constant<
    std::size_t,
    compute_bit_count<T>()
> {};

For every integral type T such that std::is_integral<T>::value is true except bool do I have the guarantee, by the standard, that:

  • bit_count_1, bit_count_2 and bit_count_3 have the same value N
  • T x = 1; x <<= (N - 1) is well defined
  • T x = ~static_cast<T>(0); x >>= (N - 1) is well defined

I am currently working on a C++ proposal, so I need to be sure whether this is true according to the standard, or not, and for the moment it's a little unclear for me.

like image 270
Vincent Avatar asked Oct 31 '22 12:10

Vincent


1 Answers

Yes, of course, you have!

[basic.types] 3.9\4

The value representation of an object is the set of bits that hold the value of type T.

[basic.fundamental] 3.9.1\3

The range of non-negative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the value representation of each corresponding signed/unsigned type shall be the same.

[basic.fundamental] 3.9.1\7

The representations of integral types shall define values by use of a pure binary numeration system.50

50) A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.)

But it depends on what are non-sign bits:

[numeric.limits.members] 18.3.2.4\9

For integer types, the number of non-sign bits in the representation.

If they implied, that the sign bit must be only in the so called sign-and-magnitude representation, then you would have these expressions evaluated as true:

  • bit_count_2<T>{} > bit_count_1<T>{}, and
  • bit_count_2<T>{} > bit_count_3<T>{},

for the signed integer type T represented in the two's or one's complement. So, I'd put a static_assert anyway, you know...

like image 98
Eugene Zavidovsky Avatar answered Nov 15 '22 06:11

Eugene Zavidovsky