C问题:off_t(和其他有符号整数类型)最小值和最大值

我偶尔会遇到一个整数类型(例如,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中有整数可移植性问题的注释:

Whether signed integer types are represented using sign and magnitude,two’s
complement,or ones’ complement,and whether the extraordinary value is a trap
representation or an ordinary value (6.2.6.2).

这似乎意味着只能使用三个列出的签名号码表示.这个含义是否正确,以上的宏是否与所有三种表示兼容?

其他想法:
如果有填充位,似乎函数式宏MAX_INT_VAL_STEP()会给出不正确的结果.我想知道是否有任何办法.

通过signed number representations on Wikipedia读取,对我来说,对于所有三个有符号整数表示,任何有符号整数类型的MAX将是:
符号位关闭,所有值位(全部三个)
它的MIN将是:
符号位打开,所有值位(符号和幅度)
符号位打开,所有值位关闭(一/二进制补码)

我想我可以通过这样做来测试符号和大小:

#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?而对于一个/二进制补码最小值,我需要一些方法关闭所有的值,但是将其打开.不知道如何做到这一点,而不知道值位的数量.同样是符号位保证总是比最重要的值更重要一点?

谢谢,请让我知道这是否太长了

EDIT 12/29/2010 5PM EST:
如下面的解释,得到无符号类型的最大值,(unsigned type)-1更正确的是〜0或甚至〜(无符号类型)0.使用-1时可以收集的内容与0-1相同,这将始终导致无符号类型中的最大值.

此外,由于可以确定无符号类型的最大值,因此可以确定无符号类型中有多少个值位.他向Hallvard B. Furuseth授予他的IMAX_BITS()函数式宏,他在回复question on 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) computes the number of bits in an int,and IMAX_BITS((unsigned_type)-1) computes the number of bits in an unsigned_type. Until someone implements 4-gigabyte integers,anyway:-)

然而,我的问题的核心仍然没有答案:如何通过宏来确定签名类型的最小值和最大值.我还在看这个也许答案是没有答案.

如果在大多数情况下,如果您不在StackOverflow上查看此问题,则在接受之前您将无法看到建议的答案.建议view this question on StackOverflow.

解决方法

令人惊讶的是,C在算术运算之前将类型提升到int,结果至少是int大小. (类似地,oddities包括具有类型int,而不是char的’a’字符文字.)
int a = (uint8_t)1 + (uint8_t)-1;
   /* = (uint8_t)1 + (uint8_t)255 = (int)256 */
int b = (uint8_t)1 + ~(uint8_t)0;
   /* = (uint8_t)1 + (int)-1 = (int)0 */

所以#define UINT_WHATEVER_T_MAX(〜(uint_whatever_t)0)不一定可以.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...