Number of bits in a data type

后端 未结 6 1870
半阙折子戏
半阙折子戏 2021-02-06 14:53

I have two tasks for an assignment, one return the number of bits in type int on any machine. I thought I would write my function like so:

int CountIntBitsF() {         


        
相关标签:
6条回答
  • 2021-02-06 15:24

    The fundamental unit of storage is a char. It is not always 8 bits wide. CHAR_BIT is defined in limits.h and has the number of bits in a char.

    0 讨论(0)
  • 2021-02-06 15:34

    In limits.h, UINT_MAX is the maximum value for an object of type unsigned int. Which means it is an int with all bits set to 1. So, counting the number of bits in an int:

    #include <limits.h>
    
    int intBits () {
        int x = INT_MAX;
        int count = 2; /* start from 1 + 1 because we assume
                        * that sign uses a single bit, which
                        * is a fairly reasonable assumption
                        */
    
        /* Keep shifting bits to the right until none is left.
         * We use divide instead of >> here since I personally
         * know some compilers which does not shift in zero as
         * the topmost bit
         */
        while (x = x/2) count++;
    
        return count;
    }
    
    0 讨论(0)
  • 2021-02-06 15:35

    Are you sure you want number of bits, not number of bytes? In C, for a given type T, you can find the number of bytes it takes by using the sizeof operator. The number of bits in a byte is CHAR_BIT, which usually is 8, but can be different.

    So, given a type T, the number of bits in an object of type T is:

    #include <limits.h>
    size_t nbits = sizeof(T) * CHAR_BIT
    

    Note that, except for unsigned char type, all possible combinations of nbits bits above may not represent a valid value of type T.

    For the second part, note that you can apply sizeof operator to an object as well as a type. In other words, given a type T and an object x of such type:

    T x;
    

    You can find the size of T by sizeof(T), and the size of x by sizeof x. The parentheses are optional if sizeof is used for an object.

    Given the information above, you should be able to answer your second question. Ask again if you still have issues.

    0 讨论(0)
  • 2021-02-06 15:37

    If you want the number of bits used to store an int in memory, use Justin's answer, sizeof(int)*CHAR_BIT. If you want to know the number of bits used in the value, use slebetman's answer.

    Although to get the bits in an INT, you should probably use INT_MAX rather than UINT_MAX. I can't remember whether C99 actually guarantees that int and unsigned int are the same width, or just that they're the same storage size. I suspect only the latter, since in 6.2.6.2 we have "if there are M value bits in the signed type and N in the unsigned type, then M <= N", not "M = N or M = N-1".

    In practice, integral types don't have padding bits in any implementation I've used, so you most likely get the same answer for all, +/- 1 for the sign bit.

    0 讨论(0)
  • 2021-02-06 15:41

    It's *, not /.

    As for the second part, see the "Numerical Limits" section.

    0 讨论(0)
  • 2021-02-06 15:43

    With g++ -O2 this function evaluates to an inline constant:

    #include <climits>
    #include <stddef.h>
    #include <stdint.h>
    #include <cstdio>
    
    template <typename T>
    size_t num_bits()
    {
        return sizeof (T) * (CHAR_BIT);
    }
    
    int main()
    {
        printf("uint8_t : %d\n", num_bits<uint8_t>());
        printf("size_t : %d\n", num_bits<size_t>());
        printf("long long : %d\n", num_bits<long long>());
        printf("void* : %d\n", num_bits<void*>());
        printf("bool : %d\n", num_bits<bool>());
        printf("float : %d\n", num_bits<float>());
        printf("double : %d\n", num_bits<double>());
        printf("long double : %d\n", num_bits<long double>());
    
        return 0;
    }
    

    outputs:

    uint8_t : 8
    size_t : 32
    long long : 64
    void* : 32
    bool : 8
    float : 32
    double : 64
    long double : 96
    

    Generated X86 32-bit assember:

    ---SNIP---

    movl    $32, 8(%esp)      <--- const $32
    movl    $.LC1, 4(%esp)
    movl    $1, (%esp)
    call    __printf_chk
    movl    $64, 8(%esp)      <--- const $64
    movl    $.LC2, 4(%esp)
    movl    $1, (%esp)
    call    __printf_chk
    

    ---SNIP---

    0 讨论(0)
提交回复
热议问题