get unsigned long long addition carry

1.1k Views Asked by At

I want to get the carry bit of adding two unsigned 64-bit integers in c. I can use x86-64 asm if needed. code:

#include <stdio.h>

typedef unsigned long long llu;

int main(void){
  llu a = -1, b = -1;
  int carry = /*carry of a+b*/;
  llu res = a+b;
  printf("a+b = %llu (because addition overflowed), carry bit = %d\n", res, carry);
  return 0;
}
2

There are 2 best solutions below

3
John Bollinger On BEST ANSWER

As @EugeneSh. observes, the carry is either 0 or 1. Moreover, given that a and b both have the same unsigned type, their sum is well defined even if the arithmetic result exceeds the range of their type. Moreover, the (C) result of the sum will be less than both a and b when overflow occurs, and greater otherwise, so we can use the fact that C relational operations evaluate to either 0 or 1 to express the carry bit as

carry = (a + b) < a;

That does not require any headers, nor does it depend on a specific upper bound, or even on a and b having the same type. As long as both have unsigned types, it reports correctly on whether the sum overflows the wider of their types or unsigned int (whichever is wider), which is the same as their sum setting the carry bit. As a bonus, it is expressed in terms of the sum itself, which I think makes it clear what's being tested.

5
Eugene Sh. On

Carry can be only 0 or 1. 1 if there was a wrapping-around and 0 otherwise. The wrapping-around is happening in case a + b > ULONG_LONG_MAX is true . Note, this is in mathematical terms, not in terms of C, as if a + b is actually overflowing, then this will not work. Instead you want to rearrange it to be a > ULONG_LONG_MAX - b. So the value of carry will be:

carry = a > ULONG_LONG_MAX - b ? 1 : 0;

or any preferred style equivalent.

  • Don't forget to include limits.h.