This question already has answers here:
How do I detect unsigned integer overflow?
(31 answers)
Closed 6 years ago.
Edit (IMPORTANT): This question was more specific than the question this was marked as a duplicate against. This was asking how to do it with a boolean function. But now I know that it just doesn't work like that. This question shows that a + b = c can only be overflow checked if you write if(c - b == a) and that there is no operator independent way of checking.
Once the overflow happened, you cannot detect it
-lorro
I have been looking for a way to detect integer overflow in C++ using an if statement.
Possible pseudo code:
#include <iostream>
#include <...>
using namespace std;
bool isOverflow(...);
int main()
{
int a = INT_MAX + 1;
if (isOverflow(...))
{
cout << "Overflow" << endl;
}
else
{
cout << "No Overflow" << endl;
}
return 0;
}
bool isOverflow
{
...
}
OK to be honest this pseudo code preference may not work, but i've seen this question asked many times and have not found any useful answers. It may require unsigned or unsigned long long, although I'm not necessarily encouraging the use of those.
EDIT:
I would like to use it with a multiplication sentence with 3 numbers:
a * a * b
I am aware that there is a pow function in <math.h> but that's off topic.
I am also aware that if I want an accurate int result from pow I would use:
int(pow(base, index) + 0.5)
It depends on what sort of operation you are using and what are the types of the operands.
e.g. if you want to detect an overflow after addition, and both operands are unsigned integers, then an overflow will have occurred if the result is less than the sum of both operands.
bool overflow;
if (a+b < a)
overflow = true;
else
overflow = false;
For signed integers, you can refer to the excellent post here
Related
This question already has answers here:
bool operator ++ and --
(4 answers)
Closed 2 years ago.
why incase of boolean, overflow doesn't occur in circular fashion. eg say a=126 when you reach 128 and you increment it, a goes to -127 if range is -127 to 128. similarly for boolean it is 0 to 1 so it should move around 0101010101 and so on. please clarify
using namespace std;
int main()
{
bool a;
for (a = 1; a <= 5; a++)
cout << a;
return 0;
}
From cppreference
If the operand of the pre-increment operator is of type bool, it is set to true
If the operand of the post-increment operator is of type bool, it is set to true
Note that this behaviour was removed in C++17 and your code won't compile with newer standards (probably because it was confusing).
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
As documented here, std::bitset::operator^= returns *this. From that and from the "usual" interpretation of operators such as +=, |=, *= one could reasonably assume that given std::bitset instances (of the same size) a and b, the expression (a^=b).count() will store the result of a bitwise XOR operation in a, and that count() would return the number of bits in a that are set to true. However, as the following minimal example demonstrates, something unexpected happens:
#include <iostream>
#include <bitset>
int main()
{
constexpr unsigned int N=6;
std::bitset<N> a;
std::bitset<N> b;
a.flip();//111111
b[0]=1;
b[4]=1;//b is now 010001 (assuming least significan bit on the right end of the string)
std::cout<<"a=="<<a.to_string()<<std::endl;
std::cout<<"b=="<<b.to_string()<<std::endl;
std::cout<<"(a xor b) to string=="<<(a^=b).to_string()<<std::endl;
//Here is the unexpected part!
std::cout<<"(a xor b) count=="<<(a^=b).count()<<std::endl;
//Note that the following lines would produce the correct result
//a^=b;
//std::cout<<a.count()<<std::endl;
return 0;
}
The output is
a==111111
b==010001
(a xor b) to string==101110
(a xor b) count==6 //this is wrong!!!!! It should be 4...
A quick look at the implementation of std::bitset (see here) seems to indicate that the reference that is returned is indeed a reference to the lhs object (a in my example). So... Why is this happening?
This has nothing to do with the bitset. Consider this code:
int a = 2;
int b = 3;
std::cout << std::to_string(a *= b) << std::endl; // Prints 6.
std::cout << std::to_string(a *= b) << std::endl; // Prints 18.
You are using an assignment operator, so your variable/bitset changes every time. In your case, the second evaluation yields ((a ^ b) ^ b), which is of course the original a (which did have 6 bits set).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was writing a small Least common multiple algorithm and encountered something I don't understand. This is the first and last part of the code:
long a = 14159572;
long b = 63967072;
int rest = 4;
long long ans;
.
. // Some other code here that is not very interesting.
.
else
{
//This appears correct, prints out correct answer.
ans = b/rest;
std::cout << a*ans;
}
But if I change the last "else" to this it gives an answer that is much smaller and incorrect:
else
{
std::cout << a*(b/rest);
}
Anyone know why this is? I don't think it's an overflow since it was no negative number that came out wrong, but rather just a much smaller integer (around 6*10^8) than the actual answer (around 2.2*10^14). As far as I understand it should calculate "b/rest" first in both cases, so the answers shouldn't differ?
Difference is not order of operations but data types:
ans = b/rest; // b/rest is long which upscaled to long long
std::cout << a*ans; // a converted to long long and result is long long
vs:
std::cout << a*(b/rest); // a*(b/rest) all calculations in long
so if you change your second variant to:
std::cout << a*static_cast<long long>(b/rest);
you should see the same result.
Update to why your cast did not work, note the difference:
long a,b;
// divide `long` by `long` and upscale result to `long long`
std::cout << static_cast<long long>( a / b );
// upscale both arguments to `long long` and divide `long long` by `long long`
std::cout << a / static_cast<long long>( b );
You're still encountering overflow. Just because you're not observing a negative number doesn't mean there's no overflow.
In your case specifically, long is almost certainly a 32-bit integer, as opposed to long long which is probably a 64-bit integer.
Since the maximum value of a 32-bit signed integer is roughly 2 billion, 14159572 * (63967072 / 4) is most definitely overflowing the range.
Make sure you perform your calculations using long long numbers, or else reconsider your code to avoid overflow in the first place.
The compiler assumes data types for each operand of your math equation and does the multiplication and division according to those assumed data types (refer to "integer division"). This also applies to intermediates of the computation. This also applies to the result passed to the stream since you don't pass a variable of an explicitly defined type.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
What is the faster between the two following code? why?
In which case one can be preferred to the other?
double x = (a + b) >> 1
double x = (a + b) / 2.0
These do different things so pick the one with the functionality you like: Truncating the result down or returning the 0.5 fraction.
"Premature optimization is root of all evil". Use what is more readable, when you have perfomance issue first look for algorithms and data structures, where you can get most perfomance gain, then run profiler and optimize where is necessary.
As others have said, the two statements produce different results, especially if (a + b) is an odd value.
Also, according to the language, a and b must be integral values in order to satisfy the shifting operation.
If a and b differ in type between the two statements, you are comparing apples to elephants.
Given this demo program:
#include <iostream>
#include <cstdlib>
#include <cmath>
using std::cout;
using std::endl;
int main(void)
{
const unsigned int a = 5;
const unsigned int b = 8;
double x = (a + b) >> 1;
cout << x << endl;
double y = (a + b) / 2.0;
cout << y << endl;
return EXIT_SUCCESS;
}
The output:
6
6.5
Based on this experiment, the comparison is apples to oranges. The statement involving shifting is a different operation that dividing by a floating point number.
As far as speed goes, the second statement is slower because the expression (a + b) must be converted to double before applying the division. The division is floating point, which may be slow on platforms without hardware floating point support.
You should not concern yourself on the execution speed of either statement. Of more importance is the correctness and robustness of the program. For example, the two statements above provide different results, which is a very important concern for correctness.
Most Users would wait for a program to produce correct results than have a quick program producing incorrect results or behavior (nobody is in a hurry for a program to crash).
Management would rather you spend time completing the program than wasting time optimizing portions of the program that are executed infrequently.
If a or b is a double or float, shifting will produce incorrect results.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best way to detect integer overflow in C/C++
how do we check if any arithmetic operation like addition, multiplication or subtraction could result in an overflow?
Check the size of the operands first, and use std::numeric_limits. For example, for addition:
#include <limits>
unsigned int a, b; // from somewhere
unsigned int diff = std::numeric_limits<unsigned int>::max() - a;
if (diff < b) { /* error, cannot add a + b */ }
You cannot generally and reliably detect arithmetic errors after the fact, so you have to do all the checking before.
You can easily template this approach to make it work with any numeric type.