测试最大无符号值

时间:2010-12-27 14:54:14

标签: c++ c unsigned

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

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

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

6 个答案:

答案 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将与-1UINT_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.当然你也可以删除它完全有条件。