数据类型中的位数

时间:2010-01-19 02:56:53

标签: c sizeof

我有两个任务分配,一个返回任何机器上int类型的位数。我以为我会像这样编写我的函数:

int CountIntBitsF() {
    int x = sizeof(int) / 8;
    return x;
}

看起来不错吗?

第二部分是用宏返回任何数据类型的任何位数,宏可以从limits.h中获取。我在我的机器上查找了limits.h,还有http://www.opengroup.org/onlinepubs/007908799/xsh/limits.h.html,但我不认为我真的理解其中任何一个会返回任何数据类型中的位数。有什么想法吗?感谢。

7 个答案:

答案 0 :(得分:15)

The fundamental unit of storage is a char。它并不总是8位宽。 CHAR_BIT在limits.h中定义,并且具有char中的位数。

答案 1 :(得分:8)

它是*,而不是/

关于第二部分,请参阅“数字限制”部分。

答案 2 :(得分:3)

limits.h中,UINT_MAX是unsigned int类型对象的最大值。这意味着它是一个所有位都设置为1的int。因此,计算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;
}

答案 3 :(得分:3)

如果您想要用于在内存中存储int的位数,请使用Justin的答案sizeof(int)*CHAR_BIT。如果你想知道值中使用的位数,请使用slebetman的答案。

虽然要获取INT中的位,但您应该使用INT_MAX而不是UINT_MAX。我不记得C99是否确实保证intunsigned int宽度相同,或者只是它们的存储大小相同。我怀疑只有后者,因为在6.2.6.2中我们有“如果有符号类型中有M个值位且无符号类型中有N,那么M <= N”,而不是“M = N或M = N-1” ”

实际上,在我使用的任何实现中,整数类型都没有填充位,因此您很可能得到所有的答案,+ / - 1表示符号位。

答案 4 :(得分:2)

使用g ++ -O2,此函数的计算结果为内联常量:

#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;
}

输出:

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

生成的X86 32位声明:

--- --- 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

答案 5 :(得分:1)

您确定需要多少位,而不是字节数?在C中,对于给定类型T,您可以使用sizeof运算符找到它所需的字节数。字节中的位数为CHAR_BIT,通常为8,但可以不同。

因此,给定类型T,类型为T的对象中的位数为:

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

请注意,除unsigned char类型外,上述nbits位的所有可能组合可能不代表T类型的有效值。

对于第二部分,请注意您可以将sizeof运算符应用于对象和类型。换句话说,给定类型T和对象x

T x;

您可以sizeof(T)找到T的大小,x找到sizeof x的大小。如果sizeof用于对象,则括号是可选的。

鉴于上述信息,您应该能够回答第二个问题。再问一下你是否还有问题。

答案 6 :(得分:0)

您的公式不正确:您应该将 sizeof(int) (8) 中的字节数乘以 int 中的位数,而不是将 sizeof(int) 除以 <limits.h>一个字节,它确实在 CHAR_BIT 中定义为宏 #include <limits.h> int CountIntBitsF(void) { return sizeof(int) * CHAR_BIT; } 的值。

这是修正后的函数:

for(int i=1; i<argc; i++)
{
    strParameter = strParameter + string(argv[i]) + " ";
}