EDIT 2: Editing...
EDIT 1: as spotted by @pbsd this was not working good with some values...
I have added a way of checking the overflow and I have tested it:
#define BITS (8*sizeof(int))-1
int checked_add(int a, int b, int *rp)
{
*rp = a+b;
return (a^b) < 0 ? 0 : (a^(*rp)) < 0 ? 1 : 0) ;
}
It is around 30% faster than the fastest in the blog and I believe the code is way cleaner. What we are doing is checking if all of the values has the same sign (the "^" is just a "xor"), if so, no overflow in other case, overflow.This is the testing program (g++ compliant):
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define BITS (8*sizeof(int))-1
int checked_add2(int a, int b, int *rp) {
uint ur = (uint)a + (uint)b;
uint sr = ur >> (BITS-1);
uint sa = (uint)a >> (BITS-1);
uint sb = (uint)b >> (BITS-1);
*rp = ur;
return
(sa && sb && !sr) ||
(!sa && !sb && sr);
}
int checked_add(int a, int b, int *rp)
{
*rp = a+b;
return ((a^b) | (a^(*rp)) < 0) ? 1 : 0 ;
}
int main(int argc, char* argv[])
{
int a, b, c;
long clong;
srand(time(NULL));
for(unsigned int i = 0; i < 50000000; ++i)
{
bool overflow = false;
a = rand();
b = rand();
clong = (long)a + (long)b;
overflow = checked_add(a,b,&c);
if(clong != (long)c && !overflow)
printf("Overflow not detected %i + %i = %i \n", a, b, c);
}
return 0;
}
Time for "checked_add": 2.694sTime for "checked_add2": 3.200s
This is the dump (6 instructions so far): http://goo.gl/cnBKdS