Unsigned maximum value testing

This is the correct way to check the maximum unsigned value in C and C ++ code:

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

where foo is unsigned int , a unsigned short , etc.

+4
source share
6 answers

For C ++, I believe that you are better off using the numeric_limits pattern from <limits> :

 if (foo == std::numeric_limits<unsigned int>::max()) /* ... */ 

For C, others have already indicated the header <limits.h> and UINT_MAX .


Apparently, โ€œthe solutions allowed to denote a type are simple,โ€ so you might have:

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

I assume that you are asking this question, because at some point you do not know the specific type of your variable foo , otherwise you will naturally use UINT_MAX , etc.

For C, your approach is only valid for types with a conversion view of int or higher. This is due to the fact that before the comparison, the unsigned short value, for example, is first converted to int if all values โ€‹โ€‹match, or to unsigned int otherwise. So, your foo value will be compared with either -1 or UINT_MAX , and not with what you expect.

I don't see a simple way to run the test you want in C, since basically using foo in any type of expression will contribute to its int .

With the gcc typeof extension, this is easily possible. You just need to do something like

 if (foo == (typeof(foo))-1) 
+5
source

As already noted, you should use if (foo == std::numeric_limits<unsigned int>::max()) to get the value.

However, for completeness, C ++ -1 "probably" guarantees the maximum unsigned value when converting to unsigned (this would not be if there were unused bit patterns at the upper end of the unsigned range).

See 4.7 / 2:

If no destination type is specified, the resulting value is the smallest unsigned integer that matches the original integer (modulo 2 ^ n, where n is the number of bits used to represent the unsigned type). [Note: In the double complement view, this conversion is conceptual and there is no change in the bit scheme (if there is no truncation). ]

Please note that specifically for the case of unsigned int , due to the rules in 5/9, it seems that if any unsigned operand, the other will be automatically converted to unsigned, that you do not even need to use -1 (if I read the standard correctly) . In the case of an unsigned short code, you will need a direct check or explicit casting due to automatic integral promotion caused by == .

+2
source

using #include <limits.h> you could just do

if(foo == UINT_MAX)

if foo is an unsigned int , he rated [0 - +4 294 967 295] (if 32 bits)

More details: http://en.wikipedia.org/wiki/Limits.h

edit: in C

if you do

 #include <limits.h> #include <stdio.h> int main() { unsigned int x = -1; printf("%u",x); return 0; } 

you get the result 4294967295 (in a 32-bit system), and this is because inside, -1 is represented 11111111111111111111111111111111 in two additions. But since it is unsigned , now there is no "sign bit", so it works in the range [0-2 ^ n]

Also see: http://en.wikipedia.org/wiki/Two%27s_complement

See other answers for C++ part std::numeric_limits<unsigned int>::max()

+1
source

I would define a constant that will contain the maximum value as necessary in the design of your code. Using "-1" is confusing. Imagine that someone will change the type from unsigned int to int in the future, this will ruin your code.

0
source

Here's an attempt to do it in C. It depends on an implementation that doesn't have padding bits:

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

Or, if you can change the variable, just do something like:

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

Edit: And if you don't need the possible extended integer types defined by the implementation:

 #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 ) 

You could use sizeof(char) in the last line, of course, but I think itโ€™s the smell of the code and usually catch it grepping for the smells of the code, so I just wrote 1. Of course, you can also just delete the last conditional completely .

0
source

Source: https://habr.com/ru/post/1333474/


All Articles