campare a long variable with INT_MAX + 1 - c++

//Code here
long a = 42;
if(a > INT_MAX + 1)
When I do this comparison, a > INT_MAX + 1 actually returns true, which makes me confused.
The reason seems like INT_MAX + 1 is overflowed. But Why? INT_MAX should be just a macro which defined by a constant like 2^32 - 1, therefore INT_MAX + 1 should be just another constant value 2^32. And since a is long, then during compiling the compiler should also implicitly convert the INT_MAX + 1 to long type, which should be longer than int and not be overflowed.
I cannot understand why it is actually overflowed.
Could anybody help me? Thanks a lot.

therefore INT_MAX + 1 should be just another constant value
It is an arithmetic expression. More specifically, it is an addition operation. The addition overflows and behaviour of the program is undefined.
therefore during compiling the compiler should also implicitly convert the INT_MAX + 1 to long type
It does. But the conversion of the result happens after the operation.
You can fix the expression by using a - 1 > INT_MAX. Although that also has a failure case when A is LONG_MIN. Another approach is to convert one of the operands of the addition to a larger type (if a larger type exists on the system).

You can do:
(long long)INT_MAX + 1
In order to treat the values as 64-bit BEFORE the addition takes places, avoiding the overflow.
Keep in mind, long is 32-bit on some compilers (MSVC). long long, I believe, has a guaranty of at least 64.

INT_MAX + 1 is evaluated as an int before the comparison. It overflows and causes undefined behavior. Some implementations evaluate it to be -1 using wrap around logic. In some cases, that can be useful. You can read more about it at https://en.wikipedia.org/wiki/Integer_overflow.
If sizeof(long) is greater than sizeof(int) on your platform, you can get the expected result by using
if(a > INT_MAX + 1L)

the only thing you will have to do is just create another variable of type long and add 1 after that. here is the code for that:
long a = 42;
long b = INT_MAX;
b = b + 1;
if(a > b){
cout<<"long greater"<<b;
}

Related

Why does "unsigned int" + "unsigned int" return an "unsigned int"?

I believe that when you add two unsigned int values together, the returned value's data type will be an unsigned int.
But the addition of two unsigned int values may return a value that is larger than an unsigned int.
So why does unsigned int + unsigned int return an unsigned int and not some other larger data type?
This would have truly evil consequences:
Would you really want 1 + 1 to be a long type? And (1 + 1) + (1 + 1) would become a long long type? It would wreak havoc with the type system.
It's also possible, for example, that short, int, long, and long long are all the same size, and similarly for the unsigned versions.
So the implicit type conversion rules as they stand are probably the best solution.
You could always force the issue with something like
0UL + "unsigned int" + "unsigned int"
Let's imagine that we have a language where adding two integers results in a bigger type. So, adding two 32 bit numbers results in a 64 bit number. What would happen in expression the following expression?
auto x = a + b + c + d + e + f + g;
a + b is 64 bits. a + b + c is 128 bits. a + b + c + d is 256 bits... This becomes unmanageable very fast. Most processors don't support operations with so wide operands.
The type of a varaible does not only determine the range of values it can hold, but sloppy speaking, also how the operations are realized. If you add two unsigned values you get an unsigned result. If you want a different type as result (eg long unsigned) you could cast:
unsigned x = 42;
unsigned y = 42;
long unsigned z = static_cast<long unsigned>(x) + static_cast<long unsigned>(y);
Actually the real reason is: It is defined like that. In particular unsigned overflow is well defined in C++ to wrap around and using a wider type for the result of unsigned operators would break that behaviour.
As a contrived example, consider this loop:
for (unsigned i = i0; i != 0; ++i) {}
Note the condition! Lets assume i0 > 0, then it can only ever be false when incrementing the maximum value of unsigned results in 0. This code is obfuscated and should probably make you raise an eyebrow or two in a code-review, though it is perfectly legal. Making the result type adjust depending on the value of the result, or choosing the result type such that overflow cannot happen would break this behaviour.
Because a variable + a same type variable can be only equal to that type variable ,
(well in some cases it will but not in your case)
example:
int + int = int a int plus another int cannot be equal to a float because it dont have the properties of a float.
I hope this answers your question bye!

How to get negative remainder with remainder operator on size_t?

Consider the following code sample:
#include <iostream>
#include <string>
int main()
{
std::string str("someString"); // length 10
int num = -11;
std::cout << num % str.length() << std::endl;
}
Running this code on http://cpp.sh, I get 5 as a result, while I was expecting it to be -1.
I know that this happens because the type of str.length() is size_t which is an implementation dependent unsigned, and because of the implicit type conversions that happen with binary operators that cause num to be converted from a signed int to an unsigned size_t (more here);
this causes the negative value to become a positive one and messes up the result of the operation.
One could think of addressing the problem with an explicit cast to int:
num % (int)str.length()
This might work but it's not guaranteed, for instance in the case of a string with length larger than the maximum value of int. One could reduce the risk using a larger type, like long long, but what if size_t is unsigned long long? Same problem.
How would you address this problem in a portable and robust way?
Since C++11, you can just cast the result of length to std::string::difference_type.
To address "But what if the size is too big?":
That won't happen on 64 bit platforms and even if you are on a smaller one: When was the last time you actually had a string that took up more than half of total RAM? Unless you are doing really specific stuff (which you would know), using the difference_type is just fine; quit fighting ghosts.
Alternatively, just use int64_t, that's certainly big enough. (Though maybe looping over one on some 32 bit processors is slower than int32_t, I don't know. Won't matter for that single modulus operation though.)
(Fun fact: Even some prominent committee members consider littering the standard library with unsigned types a mistake, for reference see
this panel at 9:50, 42:40, 1:02:50 )
Pre C++11, the sign of % with negative values was implementation defined, for well defined behavior, use std::div plus one of the casts described above.
We know that
-a % b == -(a % b)
So you could write something like this:
template<typename T, typename T2>
constexpr T safeModulo(T a, T2 b)
{
return (a >= 0 ? 1 : -1) * static_cast<T>(std::llabs(a) % b);
}
This won't overflow in 99.98% of the cases, because consider this
safeModulo(num, str.length());
If std::size_t is implemented as an unsigned long long, then T2 -> unsigned long long and T -> int.
As pointed out in the comments, using std::llabs instead of std::abs is important, because if a is the smallest possible value of int, removing the sign will overflow. Promoting a to a long long just before won't result in this problem, as long long has a larger range of values.
Now static_cast<int>(std::llabs(a) % b) will always result in a value that is smaller than a, so casting it to int will never overflow/underflow. Even if a gets promoted to an unsigned long long, it doesn't matter because a is already "unsigned" from std::llabs(a), and so the value is unchanged (i.e. didn't overflow/underflow).
Because of the property stated above, if a is negative, multiply the result with -1 and you get the correct result.
The only case where it results in undefined behavior is when a is std::numeric_limits<long long>::min(), as removing the sign overflows a, resulting in undefined behavior. There is probably another way to implement the function, I'll think about it.

Compile-time calculation of bits needed to represent a range

I need to calculate at compile-time the number of bits needed to represent a range.
For an unsigned range from 0 to n it is simple:
constexpr unsigned bits_to_represent(uintmax_t n)
{
return n > 0
? 1 + bits_to_represent(n/2)
: 0;
}
For a signed range, I have:
constexpr unsigned bits_in_range(intmax_t min,intmax_t max)
{
return bits_to_represent(max >= 0
? static_cast<uintmax_t>(max) - min
: max - min);
}
However this causes MSVC 2015 (recently updated) to complain:
warning C4308: negative integral constant converted to unsigned type
Can you explain why this happens? As a work-around, I static_cast min to uintmax_t, but I do not like this solution as it seems less portable than my preferred solution and probably even is undefined behaviour, even though I am sceptical is that can happen at compile time.
I'm not sure exactly why MSVC is giving a warning, but one thing that you are doing that could cause bad behavior is mixing signed and unsigned integers in arithmetic operations and comparisons.
You can read this for examples of problems caused by this: http://blog.regehr.org/archives/268
I would try rewriting your function like this:
constexpr unsigned bits_in_range(intmax_t min,intmax_t max)
{
return bits_to_represent(
static_cast<uintmax_t>(max) - static_cast<uintmax_t>(min));
}
This way is more programmer friendly. When you do arithmetic operations on mismatched integer types, the compiler is going to have to do implicit conversions to make them match. This way, it doesn't have to do that. Even if max and min are negative, this will still give well-defined and correct results, if you are sure that max >= min.
Do it in 4 parts. Each of min max at least zero.
If they share the same sign (with 0 as positive), 2s complement integers can have their difference represented as part of their own type.
That leaves max<min and max positive and min negative cases.
If we assume uint_max_t is big enough, arithmetic and conversion to that type all behaves according to math mod 2^n.
So unsigned(a)-unsigned(b) will actually be the unsigned distance to get from b to a as signed integers.
C = A-B mod X
C = A-B + kX
B+C=A+kX
With C positive and less than X, and X larger than B-A, gives us C must be the delta.
Thank you for your comments even though they did not explain the Microsoft warning. Clang compiles cleanly, so it might be a bug in the compiler.
Due to the nature of conversion from signed to unsigned values in C++ the correct answer will be obtained by simply casting both values (again assuming that min <= max):
constexpr unsigned bits_in_range(intmax_t min,intmax_t max)
{
return bits_to_represent(static_cast<largest_uint>(max) -
static_cast<largest_uint>(min));
}
The validity of the code can be inferred from this part of the draft standard (I looked at the newest draft but am confident that there has not been a change here).
4.7 Integral conversions [conv.integral]
If the destination type is unsigned, the resulting value is the least > unsigned integer congruent to the source
integer (modulo 2n where n is the number of bits used to represent the
unsigned type).

Macro to calculate maximum number in C++ produces incorrect results

Variable c is assigned negative one. I can't understand why this code is producing incorrect results as there are parentheses around the macro arguments. Is this a bug or is it a new feature? Using vs2013.
#define max(a,b) (((a) > (b)) ? (a) : (b))
char *buf = "";
int c = max(1024, strlen(buf) - 1);
std::strlen returns its value as a std::size_t, an implementation-defined unsigned type.
To subtract strlen(buf) (std::size_t) and 1 (int), they need to be converted to a common type. How that happens depends on the rank of the two types, but apparently on your system, both end up converted to unsigned int.
And in unsigned int arithmetic, 0 - 1 is MAX_UINT.
max(1024, MAX_UINT) correctly evaluates as MAX_UINT.
Then that gets implicitly converted back to int, becoming the value -1.
Use (signed)strlen(buf)-1, and it will yield the expected result.
As a side note, max(1024, strlen(buf)-1) generates two calls to function strlen, so you might want to store the result of strlen(buf)-1 in a signed variable before passing it to the max macro.
The problem here is that strlen returns a size_t which is unsigned. Since strlen("") == 0, 0 - 1 wraps around to 0xFFFFFFFF, which is much larger than 1024. When c gets converted to signed int, the result is -1. Try int c = max(1024, (int)strlen(buf) - 1);

c++ illogical >= comparison when dealing with vector.size() most likely due to size_type being unsigned

I could use a little help clarifying this strange comparison when dealing with vector.size() aka size_type
vector<cv::Mat> rebuiltFaces;
int rebuildIndex = 1;
cout << "rebuiltFaces size is " << rebuiltFaces.size() << endl;
while( rebuildIndex >= rebuiltFaces.size() ) {
cout << (rebuildIndex >= rebuiltFaces.size()) << " , " << rebuildIndex << " >= " << rebuiltFaces.size() << endl;
--rebuildIndex;
}
And what I get out of the console is
rebuiltFaces size is 0
1 , 1 >= 0
1 , 0 >= 0
1 , -1 >= 0
1 , -2 >= 0
1 , -3 >= 0
If I had to guess I would say the compiler is blindly casting rebuildIndex to unsigned and the +- but is causing things to behave oddly, but I'm really not sure. Does anyone know?
As others have pointed out, this is due to the somewhat
counter-intuitive rules C++ applies when comparing values with different
signedness; the standard requires the compiler to convert both values to
unsigned. For this reason, it's generally considered best practice to
avoid unsigned unless you're doing bit manipulations (where the actual
numeric value is irrelevant). Regretfully, the standard containers
don't follow this best practice.
If you somehow know that the size of the vector can never overflow
int, then you can just cast the results of std::vector<>::size() to
int and be done with it. This is not without danger, however; as Mark
Twain said: "It's not what you don't know that kills you, it's what you
know for sure that ain't true." If there are no validations when
inserting into the vector, then a safer test would be:
while ( rebuildFaces.size() <= INT_MAX
&& rebuildIndex >= (int)rebuildFaces.size() )
Or if you really don't expect the case, and are prepared to abort if it
occurs, design (or find) a checked_cast function, and use it.
On any modern computer that I can think of, signed integers are represented as two's complement. 32-bit int max is 0x7fffffff, and int min is 0x80000000, this makes adding easy when the value is negative. The system works so that 0xffffffff is -1, and adding one to that causes the bits to all roll over and equal zero. It's a very efficient thing to implement in hardware.
When the number is cast from a signed value to an unsigned value the bits stored in the register don't change. This makes a barely negative value like -1 into a huge unsigned number (unsigned max), and this would make that loop run for a long time if the code inside didn't do something that would crash the program by accessing memory it shouldn't.
Its all perfectly logical, just not necessarily the logic you expected.
Example...
$ cat foo.c
#include <stdio.h>
int main (int a, char** v) {
unsigned int foo = 1;
int bar = -1;
if(foo < bar) printf("wat\n");
return 0;
}
$ gcc -o foo foo.c
$ ./foo
wat
$
In C and C++ languages when unsigned type has the same or greater width than signed type, mixed signed/unsigned comparisons are performed in the domain of unsigned type. The singed value is implicitly converted to unsigned type. There's nothing about the "compiler" doing anything "blindly" here. It was like that in C and C++ since the beginning of times.
This is what happens in your example. Your rebuildIndex is implicitly converted to vector<cv::Mat>::size_type. I.e. this
rebuildIndex >= rebuiltFaces.size()
is actually interpreted as
(vector<cv::Mat>::size_type) rebuildIndex >= rebuiltFaces.size()
When signed value are converted to unsigned type, the conversion is performed in accordance with the rules of modulo arithmetic, which is a well-known fundamental principle behind unsigned arithmetic in C and C++.
Again, all this is required by the language, it has absolutely nothing to do with how numbers are represented in the machine etc and which bits are stored where.
Regardless of the underlying representation (two's complement being the most popular, but one's complement and sign magnitude are others), if you cast -1 to an unsigned type, you will get the largest number that can be represented in that type.
The reason is that unsigned 'overflow' behavior is strictly defined as converting the value to the number between 0 and the maximum value of that type by way of modulo arithmetic. Essentially, if the value is larger than the largest value, you repeatedly subtract the maximum value until your value is in range. If your value is smaller than the smallest value (0), you repeatedly add the largest value until it's in range. So if we assume a 32-bit size_t, you start with -1, which is less than 0. Therefore, you add 2^32, giving you 2^32 - 1, which is in range, so that's your final value.
Roughly speaking, C++ defines promotion rules like this: any type of char or short is first promoted to int, regardless of signedness. Smaller types in a comparison are promoted up to the larger type in the comparison. If two types are the same size, but one is signed and one is unsigned, then the signed type is converted to unsigned. What is happening here is that your rebuildIndex is being converted up to the unsigned size_t. 1 is converted to 1u, 0 is converted to 0u, and -1 is converted to -1u, which when cast to an unsigned type is the largest value of type size_t.