Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check if A+B exceed long long? (both A and B is long long) [duplicate]

Tags:

I have two numbers: A and B. I need to calculate A+B somewhere in my code. Both A and B are long long, and they can be positive or negative.

My code runs wrong, and I suspect the problem happens when calculating A+B. I simply want to check if A+B exceed long long range. So, any method is acceptable, as I only use it for debug.

like image 601
abcdabcd987 Avatar asked Apr 10 '13 08:04

abcdabcd987


People also ask

Is there something bigger than unsigned long long?

A double or long double can typically represent numbers with larger magnitudes than a long long , but often with less precision (e.g., frequently 53 bits vs., 63 bits for a long long). If you want a larger integer type, you'll typically want to use a library.

What is the difference between unsigned long and unsigned long long?

Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).

How do you use long long in CPP?

long Type ModifierIf we need to store a large integer (in the range -2147483647 to 2147483647), we can use the type specifier long . For example, // large integer long b = 123456; Note: long is equivalent to long int .


2 Answers

Overflow is possible only when both numbers have the same sign. If both are positive, then you have overflow if mathematically A + B > LLONG_MAX, or equivalently B > LLONG_MAX - A. Since the right hand side is non-negative, the latter condition already implies B > 0. The analogous argument shows that for the negative case, we also need not check the sign of B (thanks to Ben Voigt for pointing out that the sign check on B is unnecessary). Then you can check

if (A > 0) {     return B > (LLONG_MAX - A); } if (A < 0) {     return B < (LLONG_MIN - A); } return false; 

to detect overflow. These computations cannot overflow due to the initial checks.

Checking the sign of the result of A + B would work with guaranteed wrap-around semantics of overflowing integer computations. But overflow of signed integers is undefined behaviour, and even on CPUs where wrap-around is the implemented behaviour, the compiler may assume that no undefined behaviour occurs and remove the overflow-check altogether when implemented thus. So the check suggested in the comments to the question is highly unreliable.

like image 65
Daniel Fischer Avatar answered Oct 19 '22 12:10

Daniel Fischer


Something like the following:

long long max = std::numeric_limits<long long>::max(); long long min = std::numeric_limits<long long>::min();  if(A < 0 && B < 0)      return B < min - A; if(A > 0 && B > 0)     return B > max - A;  return false; 

We can reason about this as follows:

  • If A and B are opposite sign, they cannot overflow - the one greater than zero would need to be greater than max or the one less than zero would need to be less than min.

  • In the other cases, simple algebra suffices. A + B > max => B > max - A will overflow if they are both positive. Otherwise if they are both negative, A + B < min => B < min - A.

like image 43
Yuushi Avatar answered Oct 19 '22 11:10

Yuushi