6

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

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

这看起来对吗?

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

4

7 回答 7

16

存储的基本单位是 char。它并不总是 8 位宽。CHAR_BIT 在limits.h 中定义,具有char 中的位数。

于 2010-01-19T03:14:10.260 回答
9

*,不是/

至于第二部分,请参阅“数值限制”部分。

于 2010-01-19T02:58:12.230 回答
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;
}
于 2010-01-19T03:15:26.650 回答
3

如果您想要用于在内存中存储 int 的位数,请使用贾斯汀的答案,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。

于 2010-01-19T03:28:10.443 回答
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 位汇编:

---剪辑---

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

---剪辑---

于 2012-11-13T21:06:19.560 回答
1

您确定要位数而不是字节数吗?在 C 中,对于给定的 type T,您可以使用运算符找到它占用的字节数sizeof。一个字节中的位数为CHAR_BIT,通常为 8,但也可以不同。

因此,给定一个 type T,该类型对象的位数T为:

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

请注意,除了unsigned chartype 之外,nbits上述所有可能的位组合可能不代表 type 的有效值T

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

T x;

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

鉴于以上信息,您应该能够回答您的第二个问题。再次询问您是否仍有问题。

于 2010-01-19T03:26:18.690 回答
0

您的公式不正确:您应该将( )中的字节数乘以字节中的位数,而不是除以sizeof(int),这实际上定义为宏的值。8intsizeof(int)<limits.h>CHAR_BIT

这是修正后的函数:

#include <limits.h>

int CountIntBitsF(void) {
    return sizeof(int) * CHAR_BIT;
}
于 2021-03-20T18:16:05.577 回答