测试最大无符号值

这是在C和C ++代码中测试最大无符号值的正确方法:

if(foo == -1) { // at max possible value } 

其中foo是unsigned intunsigned short ,依此类推。

对于C ++,我相信您最好使用标头中的numeric_limits模板:

 if (foo == std::numeric_limits::max()) /* ... */ 

对于C,其他人已经指出了头和UINT_MAX


显然,“允许命名类型的解决方案很容易”,因此您可以:

 template inline bool is_max_value(const T t) { return t == std::numeric_limits::max(); } [...] if (is_max_value(foo)) /* ... */ 

我想你问这个问题,因为在某个时刻你不知道变量foo的具体类型,否则你自然会使用UINT_MAX等。

对于C,您的方法仅适用于转换等级为int或更高的类型。 这是因为在比较unsigned short值之前,例如,如果所有值都适合,则首先转换为int ,否则转换为unsigned int 。 那么你的价值foo将被比作-1UINT_MAX ,而不是你所期望的。

我没有看到在C中实现您想要的测试的简单方法,因为在任何类型的表达式中基本上使用foo会将其提升为int

使用gcc的扩展类型,这很容易实现。 你只需要做类似的事情

 if (foo == (typeof(foo))-1) 

如前所述,您应该使用if (foo == std::numeric_limits::max())来获取值。

但是为了完整性,在C ++中, -1 “可能”保证在转换为无符号时是最大无符号值(如果在无符号值范围的上端存在未使用的位模式,则不会出现这种情况)。

见4.7 / 2:

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 ^ n,其中n是用于表示无符号类型的位数)。 [注意:在二进制补码表示中,此转换是概念性的,并且位模式没有变化(如果没有截断)。 ]

请注意,特别是对于unsigned int情况,由于5/9中的规则,如果任一操作数是无符号的,另一个将自动转换为无符号,因此您甚至不需要转换-1 (如果我’正确阅读标准)。 在unsigned short的情况下,由于==引起的自动积分提升,您需要直接检查或显式转换。

使用#include 你可以做到

if(foo == UINT_MAX)

如果foo是unsigned int它的值为[0 – +4,294,967,295](如果是32位)

更多: http : //en.wikipedia.org/wiki/Limits.h

编辑:在C

如果你这样做

 #include  #include  int main() { unsigned int x = -1; printf("%u",x); return 0; } 

你将得到结果4294967295 (在一个32位系统中),这是因为在内部,-1由二进制补码中的11111111111111111111111111111111表示。 但因为它是unsigned ,所以现在没有“符号位”因此使其在[0-2 ^ n]范围内工作

另见: http : //en.wikipedia.org/wiki/Two%27s_complement

请参阅其他C++部分的答案std::numeric_limits::max()

我将定义一个常量,它将根据代码设计的需要保持最大值。 使用“-1”令人困惑。 想象一下,将来有人会将类型从unsigned int更改为int,这会弄乱你的代码。

这是尝试在C中执行此操作。这取决于没有填充位的实现:

 #define IS_MAX_UNSIGNED(x) ( (sizeof(x)>=sizeof(int)) ? ((x)==-1) : \ ((x)==(1< 

或者,如果您可以修改变量,只需执行以下操作:

 if (!(x++,x--)) { /* x is at max possible value */ } 

编辑:如果您不关心可能的实现定义的扩展整数类型:

 #define IS_MAX_UNSIGNED(x) ( (sizeof(x)>=sizeof(int)) ? ((x)==-1) : \ (sizeof(x)==sizeof(short)) ? ((x)==USHRT_MAX) : \ (sizeof(x)==1 ? ((x)==UCHAR_MAX) : 42 ) 

当然,你可以在最后一行使用sizeof(char) ,但我认为这是一种代码气味,并且通常会抓住代码气味,所以我只写了1.当然你也可以完全删除最后一个条件。