c - 如何计算有符号位域的最大支持值?

标签 c c99 bit-fields c11

假设我的项目包含来自第 3 方库的 header ,其中包含:

struct foo {
    signed int x:4;
};

如果不假设位域的宽度始终为 4,并且不依赖于实现定义的行为,我如何确定可以存储在成员 x 中的最大值?

最佳答案

由于位域的大小不能用 sizeof 计算,这可以帮助:

#include <stdio.h>

struct foo {
    signed int x: 4;
};

#define BIT(n) (1l << (n))
#define BIT_MASK(len) (BIT(len) - 1)

int main(void)
{
    struct foo f = {0};
    long i = 0;

    while (f.x >= 0) {
        f.x = BIT_MASK(++i);
    }
    printf("bits=%ld max=%ld\n", i, BIT_MASK(i));
    return 0;
}

左移直到 f.x 为负。

编辑:

上面的代码是实现定义的,检查这个,我认为这行得通(但你必须处理 BIG ENDIAN):

#include <stdio.h>
#include <string.h>

struct foo {
    signed int x: 4;
};

#define BIT(n) (1l << (n))
#define BIT_MASK(len) (BIT(len) - 1)

int main(void)
{
    long x, i = 0;
    struct foo f;

    f.x = -1;
    memcpy(&x, &f, sizeof(f));
    while (1) {
        if (!(x & BIT(++i))) break; 
    }
    printf("bits=%ld max=%ld\n", i, BIT_MASK(i));
    return 0;
}

正如您现在看到的,它不超过 2^(n-1)-1(适用于 long)

关于c - 如何计算有符号位域的最大支持值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17759637/

相关文章:

c - 存储随机数 C 的值

c - 位域在 union 中未按预期工作

c - 将位字段与 union 一起使用是否有效?

c - 使用 gethostbyname 的 DNS

无符号整数递增会导致未定义的行为吗?

c - 如何从 C99 函数声明中确定返回类型、参数、函数名

c - 如何管理 union 和位域

c - C中的 float 学获取随机数

c - epoll 是线程安全的吗?

c - Cygwin 的标准#ifdef