这是在C和C ++代码中测试最大无符号值的正确方法:
if(foo == -1)
{
// at max possible value
}
其中foo是unsigned int
,unsigned short
,依此类推。
答案 0 :(得分:12)
对于C ++,我认为您最好使用<limits>
标题中的numeric_limits
模板:
if (foo == std::numeric_limits<unsigned int>::max())
/* ... */
对于C,其他人已经指出了<limits.h>
标题和UINT_MAX
。
显然,“允许命名类型的解决方案很容易”,因此您可以:
template<class T>
inline bool is_max_value(const T t)
{
return t == std::numeric_limits<T>::max();
}
[...]
if (is_max_value(foo))
/* ... */
答案 1 :(得分:5)
我想你问这个问题,因为在某个时刻你不知道变量foo
的具体类型,否则你自然会使用UINT_MAX
等。
对于C,您的方法仅适用于转化级别为int
或更高的类型。这是因为在比较之前unsigned short
值,例如,如果所有值都适合,则首先转换为int
,否则转换为unsigned int
。那么,您的价值foo
将与-1
或UINT_MAX
进行比较,而不是您所期望的。
我没有看到在C中实现您想要的测试的简单方法,因为在任何类型的表达式中基本上使用foo
会将其提升为int
。
使用gcc的typeof
扩展名很容易实现。你只需做类似
if (foo == (typeof(foo))-1)
答案 2 :(得分:2)
如前所述,您应该使用if (foo == std::numeric_limits<unsigned int>::max())
来获取值。
但是为了完整性,在C ++ -1
中,“可能”被保证为转换为无符号时的最大无符号值(如果在无符号的上端有未使用的位模式,则不会出现这种情况)价值范围)。
见4.7 / 2:
如果目标类型是无符号的,则结果值为 最小符号无符号整数 源整数(模2 ^ n,其中n 是用于的位数 代表无符号类型)。 [注意: 在二进制补码表示中, 这种转换是概念性的 位模式没有变化 (如果没有截断)。 ]
请注意,特别针对unsigned int
情况,由于5/9中的规则,如果任一操作数是无符号的,另一个将自动转换为无符号,因此您甚至不需要转换-1
(如果我正确地阅读标准)。在无符号短片的情况下,由于==
引起的自动积分提升,您需要直接检查或显式转换。
答案 3 :(得分:1)
使用#include <limits.h>
你可以做到
if(foo == UINT_MAX)
如果foo是unsigned int
,它的值为[0 - +4,294,967,295](如果是32位)
更多:http://en.wikipedia.org/wiki/Limits.h
编辑:在C
如果你这样做
#include <limits.h>
#include <stdio.h>
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<unsigned int>::max()
答案 4 :(得分:0)
我会定义一个常量,它将根据代码设计的需要保持最大值。使用“-1”令人困惑。想象一下,将来有人会将类型从unsigned int更改为int,这会弄乱你的代码。
答案 5 :(得分:0)
这是尝试在C中执行此操作。这取决于没有填充位的实现:
#define IS_MAX_UNSIGNED(x) ( (sizeof(x)>=sizeof(int)) ? ((x)==-1) : \
((x)==(1<<CHAR_BIT*sizeof(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.当然你也可以删除它完全有条件。