我偶尔会遇到整数类型(例如 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 )
有符号整数类型看起来会更加困难。我见过几种不同的可能解决方案,但只有一个似乎是可移植的。要么就是它不正确。我在谷歌搜索 OFF_T_MAX 和 OFF_T_MIN 时找到了它。感谢 Christian Biere:
#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中有有关整数可移植性问题的注释:
有符号整数类型是使用符号和大小、2的补码还是1的补码表示,以及非常规值是陷阱表示还是普通值(6.2.6.2)。
这似乎意味着只能使用这三种列出的带符号数表示。这个推论是正确的吗?这些宏是否与所有三种表示兼容?
其他想法:
如果存在填充位,函数式宏
MAX_INT_VAL_STEP()
似乎会给出错误的结果。我想知道是否有任何方法可以解决这个问题。
阅读维基百科上的signed number representations后,我发现对于所有三种带符号整数表示,任何带符号整数类型的最大值都将是:
符号位关闭,所有值位打开(所有三种)
而其最小值可能是:
符号位打开,所有值位打开(符号和大小)
符号位打开,所有值位关闭(一/二的补码)
我认为我可以通过执行此操作来测试符号和大小:
#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
吗?对于补码的最小值,我需要一些方法将所有值位关闭但保留符号位。不知道如何在不知道值位数的情况下完成此操作。另外,符号位是否保证始终比最高有效值位更重要一个?谢谢,请告诉我这篇文章是否太长了。
编辑 12/29/2010 5PM EST:
如下面ephemient所回答的,要获取无符号类型的最大值,(unsigned type)-1
比~0
甚至比~(unsigned type)0
更正确。据我所知,当你使用-1时,它与0-1是一样的,这将始终导致无符号类型中的最大值。
此外,由于可以确定无符号类型的最大值,因此可以确定无符号类型中有多少个值位。感谢Hallvard B. Furuseth发布的IMAX_BITS()函数宏,他在comp.lang.c的问题回复中发布了该宏。
/* 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中的位数。直到有人实现了4GB整数为止:-)
然而,我的问题的核心仍未得到解答:如何通过宏确定有符号类型的最小值和最大值。我仍在研究中。也许答案是没有答案。
如果您不是在StackOverflow上查看此问题,则在大多数情况下,您无法在被接受之前看到提出的答案。建议在StackOverflow上查看此问题。
MAX_INT_VAL_STEP
就会出错。我有一个相关的问题,从来没有得到令人满意的答案:https://dev59.com/3W865IYBdhLWcg3wKLNP - R.. GitHub STOP HELPING ICE#ifdef
来处理它们。 - Kaz