【发布时间】:2011-05-29 17:05:25
【问题描述】:
我偶尔会遇到一种整数类型(例如 POSIX 有符号整数类型off_t),在这种情况下,为它的最小值和最大值设置一个宏会很有帮助,但我不知道如何制作一个真正的宏便携的。
对于无符号整数类型,我一直认为这很简单。 0 为最小值,~0 为最大值。我已经阅读了几个不同的 SO 线程,这些线程建议使用 -1 而不是 ~0 以实现可移植性。这里有一个有趣的线程:
c++ - Is it safe to use -1 to set all bits to true? - Stack Overflow
但是,即使在阅读了有关此问题的内容后,我仍然感到困惑。另外,我正在寻找同时符合 C89 和 C99 的东西,所以我不知道是否适用相同的方法。假设我有一种uint_whatever_t。我不能先转换为 0 然后按位补码吗?这样可以吗?:
#define UINT_WHATEVER_T_MAX ( ~ (uint_whatever_t) 0 )
有符号整数类型看起来更难破解。我见过几种不同的可能解决方案,但只有one 似乎是可移植的。要么是这样,要么是不正确的。我在搜索 OFF_T_MAX 和 OFF_T_MIN 时发现了它。感谢克里斯蒂安·比尔:
#define MAX_INT_VAL_STEP(t) \
((t) 1 << (CHAR_BIT * sizeof(t) - 1 - ((t) -1 < 1)))
#define MAX_INT_VAL(t) \
((MAX_INT_VAL_STEP(t) - 1) + MAX_INT_VAL_STEP(t))
#define MIN_INT_VAL(t) \
((t) -MAX_INT_VAL(t) - 1)
[...]
#define OFF_T_MAX MAX_INT_VAL(off_t)
我找不到任何关于 C89 中不同允许类型的有符号整数表示的信息,但 C99 在 §J.3.5 中有关于整数可移植性问题的说明:
有符号整数类型是否使用符号和大小表示,二进制 补码还是个补码,异常值是否是陷阱 表示或普通值(6.2.6.2)。
这似乎意味着只能使用这三个列出的有符号数字表示。含义是否正确,上述宏是否兼容所有三种表示?
其他想法:
如果有填充位,类似函数的宏
MAX_INT_VAL_STEP() 似乎会给出不正确的结果。我想知道有没有办法解决这个问题。
通读signed number representations on Wikipedia 我突然想到,对于所有三个有符号整数表示,任何有符号整数类型的 MAX 将是:
符号位关闭,所有值位打开(全部三个)
它的 MIN 可以是:
符号位打开,所有值位都打开(符号和幅度)
符号位打开,所有值位关闭(1/2 补码)
我想我可以通过这样做来测试符号和大小:
#define OFF_T_MIN ( ( ( (off_t)1 | ( ~ (off_t) -1 ) ) != (off_t)1 ) ? /* sign and magnitude minimum value here */ : /* ones and twos complement minimum value here */ )
然后,由于符号和幅度是符号位,并且所有值位在这种情况下 off_t 的最小值不是 ~ (off_t) 0 吗?对于一个/两个补码最小值,我需要一些方法来关闭所有值位,但保留符号位。在不知道值位数的情况下不知道如何执行此操作。符号位是否保证总是比最高有效值位高一个?
谢谢,如果这篇文章太长,请告诉我
编辑 2010 年 12 月 29 日下午 5 点 EST:
正如 ehemient 在下面得到无符号类型最大值所回答的那样,(unsigned type)-1 比~0 甚至~(unsigned type)0 更正确。据我所知,当您使用 -1 时,它与 0-1 相同,这始终会导致无符号类型的最大值。
此外,由于可以确定无符号类型的最大值,因此可以确定无符号类型中有多少值位。感谢 Hallvard B. Furuseth 在回复question on comp.lang.c
时发布的类似 IMAX_BITS() 函数的宏/* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */
#define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 \
+ (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3))
IMAX_BITS(INT_MAX) 计算 int 中的位数,而 IMAX_BITS((unsigned_type)-1) 计算 unsigned_type 中的位数。无论如何,直到有人实现 4 GB 整数:-)
然而,我的问题的核心仍未得到解答:如何通过宏确定 signed 类型的最小值和最大值。我还在调查这个。也许答案是没有答案。
如果您在大多数情况下没有在 StackOverflow 上查看此问题,则在被接受之前您无法看到建议的答案。建议view this question on StackOverflow。
【问题讨论】:
-
确实,
MAX_INT_VAL_STEP会在有任何填充位时中断。我有一个相关的问题,我从来没有得到满意的答案:stackoverflow.com/questions/3957252/… -
@R C 编译器针对哪些平台在有符号整数类型中有填充位?如有必要,也许可以使用特定于这些平台的
#ifdef来处理这些问题。 -
从 C11 开始,您可以为此使用
_Generic宏。
标签: c binary bit-manipulation bitwise-operators