13

I need to know whether an integer is 32 bits long or not (I want to know if it's exactly 32 bits long (8 hexadecimal characters). How could I achieve this in C++? Should I do this with the hexadecimal representation or with the unsigned int one?

My code is as follows:

mistream.open("myfile.txt");

if(mistream)
{
    for(int i=0; i<longArray; i++)
    {
        mistream >> hex >> datos[i];        
    }
}

mistream.close();

Where mistream is of type ifstream, and datos is an unsigned int array

Thank you

Useless
  • 64,155
  • 6
  • 88
  • 132
fergaral
  • 2,077
  • 6
  • 17
  • 34
  • 6
    use `` and compute `sizeof(int)*CHAR_BIT` or test `INT_MAX/INT_MIN` – chux - Reinstate Monica Mar 26 '15 at 17:46
  • I am not sure whether you want to know how many bits a variable of type `int` uses in your platform, or how many bits are necessary to represent a specifi integer value. In integer might take 32 bits but it takes only 1 bit to represent the value 0. – R Sahu Mar 26 '15 at 17:49
  • 1
    A non-portable way to do it is to use non-standard intrinsics. Most machines has instructions to count leading zeros or leading redundant sign bits. – user3528438 Mar 26 '15 at 17:51
  • To be clear: are you interested in knowing if the _type_ is 32 bits or if the _value_ is between `power(2,31) and power(2,32)-1` or something else? – chux - Reinstate Monica Mar 26 '15 at 17:56
  • Yes @chux I am interested in knowing if the value is between power(2, 31) and power(2, 32) - 1. Could you help me? Thank you – fergaral Mar 26 '15 at 18:30

6 Answers6

22
std::numeric_limits<unsigned>::digits

is a static integer constant (or constexpr in C++11) giving the number of bits (since unsigned is stored in base 2, it gives binary digits).

You need to #include <limits> to get this, and you'll notice here that this gives the same value as Thomas' answer (while also being generalizable to other primitive types)


For reference (you changed your question after I answered), every integer of a given type (eg, unsigned) in a given program is exactly the same size.

What you're now asking is not the size of the integer in bits, because that never varies, but whether the top bit is set. You can test this trivially with

bool isTopBitSet(uint32_t v) {
  return v & 0x80000000u;
}

(replace the unsigned hex literal with something like T{1} << (std::numeric_limits<T>::digits-1) if you want to generalise to unsigned T other than uint32_t).

Useless
  • 64,155
  • 6
  • 88
  • 132
7

As already hinted in a comment by @chux, you can use a combination of the sizeof operator and the CHAR_BIT macro constant. The former tells you (at compile-time) the size (in multiples of sizeof(char) aka bytes) of its argument type. The latter is the number of bits to the byte (usually 8).

You can encapsulate this nicely into a function template.

#include <climits>   // CHAR_BIT
#include <cstddef>   // std::size_t
#include <iostream>  // std::cout, std::endl

template <typename T>
constexpr std::size_t
bit_size() noexcept
{
  return sizeof(T) * CHAR_BIT;
}

int
main()
{
  std::cout << bit_size<int>() << std::endl;
  std::cout << bit_size<long>() << std::endl;
}

On my implementation, it outputs 32 and 64.

Since the function is a constexpr, you can use it in static contexts, such as in static_assert<bit_size<int>() >= 32, "too small");.

5gon12eder
  • 24,280
  • 5
  • 45
  • 92
5

Try this:

#include <climits>

unsigned int bits_per_byte = CHAR_BIT;
unsigned int bits_per_integer = CHAR_BIT * sizeof(int);

The identifier CHAR_BIT represents the number of bits in a char.

The sizeof returns the number of char locations occupied by the integer.

Multiplying them gives us the number of bits for an integer.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

OP said "if it's exactly 32 bits long (8 hexadecimal characters)" and further with ".. interested in knowing if the value is between power(2, 31) and power(2, 32) - 1". So it is a little fuzzy on negative 32-bit numbers.

Certainly OP wants to know the result based on the value and not the type.

bool integer_is_32_bits_long(int x) = 
    // cope with 32-bit int
    ((INT_MAX == 0x7FFFFFFF) && (x < 0)) ||
    // larger 32-bit int
    ((INT_MAX >  0x7FFFFFFF) && (x >= 0x80000000) && (x <= 0xFFFFFFFF));

Of course if int is 16-bit, then the result is always false.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

I want to know if it's exactly 32 bits long (8 hexadecimal characters)

I am interested in knowing if the value is between power(2, 31) and power(2, 32) - 1

So you want to know if the upper bit is set? Then you can simply test if the number is negative:

bool upperBitSet(int x)
{
    return x < 0;
}

For unsigned numbers, you can simply shift left and back right and then check if you lost data:

bool upperBitSet(unsigned x)
{
    return (x << 1 >> 1) != x;
}
Community
  • 1
  • 1
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
-2

The simplest way probably is to check if the 32nd bit is set:

bool isReally32bitsLong(uint32_t in) {
  return (in >> 31)!=0;
}

bool isExactly32BitsLong(uint64_t in) {
  return ((in >> 31)!=0) && ((in >> 32) == 0);
}
Christopher Creutzig
  • 8,656
  • 35
  • 45