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.
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.
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).
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 .
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With