Reputation: 7136
I know that when overflow occurs in C/C++, normal behavior is to wrap-around. For example, INT_MAX+1
is an overflow.
Is possible to modify this behavior, so binary addition takes place as normal addition and there is no wraparound at the end of addition operation ?
Some Code so this would make sense. Basically, this is one bit (full) added, it adds bit by bit in 32
int adder(int x, int y)
{
int sum;
for (int i = 0; i < 31; i++)
{
sum = x ^ y;
int carry = x & y;
x = sum;
y = carry << 1;
}
return sum;
}
If I try to adder(INT_MAX, 1);
it actually overflows, even though, I amn't using +
operator.
Thanks !
Upvotes: 0
Views: 2958
Reputation: 137398
What do you want the result of INT_MAX + 1
to be? You can only fit INT_MAX
into an int
, so if you add one to it, the result is not going to be one greater. (Edit: On common platforms such as x86 it is going to wrap to the largest negative number: -(INT_MAX+1)
. The only way to get bigger numbers is to use a larger variable.
Assuming int
is 4-bytes (as is typical on x86 compilers) and you are executing an add
instruction (in 32-bit mode), the destination register simply does overflow -- it is out of bits and can't hold a larger value. It is a limitation of the hardware.
To get around this, you can hand-code, or use an aribitrarily-sized integer library that does the following:
add
instruction on the lowest-order words. If overflow occurs, the Carry flag is set.adc
instruction, which adds the two operands as usual, but takes into account the value of the Carry flag (as a value of 1.)You can see this for a 64-bit value here.
Upvotes: 1
Reputation: 137770
Overflow means that the result of an addition would exceed std::numeric_limits<int>::max()
(back in C days, we used INT_MAX
). Performing such an addition results in undefined behavior. The machine could crash and still comply with the C++ standard. Although you're more likely to get INT_MIN
as a result, there's really no advantage to depending on any result at all.
The solution is to perform subtraction instead of addition, to prevent overflow and take a special case:
if ( number > std::numeric_limits< int >::max() - 1 ) { // ie number + 1 > max
// fix things so "normal" math happens, in this case saturation.
} else {
++ number;
}
Without knowing the desired result, I can't be more specific about the it. The performance impact should be minimal, as a rarely-taken branch can usually be retired in parallel with subsequent instructions without delaying them.
Edit: To simply do math without worrying about overflow or handling it yourself, use a bignum library such as GMP. It's quite portable, and usually the best on any given platform. It has C and C++ interfaces. Do not write your own assembly. The result would be unportable, suboptimal, and the interface would be your responsibility!
Upvotes: 4