Skip to content

Instantly share code, notes, and snippets.

@zaburo-ch
Last active June 6, 2018 10:08
Show Gist options
  • Save zaburo-ch/5b6939eef9bc022dfa1e8140be6558dd to your computer and use it in GitHub Desktop.
Save zaburo-ch/5b6939eef9bc022dfa1e8140be6558dd to your computer and use it in GitHub Desktop.
[WIP] C++ int64_t overflow detection
class SafeInt64{
private:
bool overflow = false;
int64_t value = 0;
int64_t safe_add(int64_t b){
int64_t a = value;
int clz_a = __builtin_clzll(a > 0 ? a : -a);
int clz_b = __builtin_clzll(b > 0 ? b : -b);
if ( (0 < a && 0 < b && clz_a == 1 && clz_b == 1)
|| (a < 0 && b < 0 && clz_a != 1 && clz_b != 1) ){
overflow = true;
}
value = a + b;
}
int64_t safe_mul(int64_t b){
int64_t a = value;
uint64_t ua = a > 0 ? a : -a;
uint64_t ub = b > 0 ? b : -b;
int bit_a = 64 - __builtin_clzll(ua);
int bit_b = 64 - __builtin_clzll(ub);
if(bit_a + bit_b == 64){
uint64_t uc = ua * ub;
if(__builtin_clzll(uc) == 0){
overflow = true;
}
}else if(bit_a + bit_b > 64){
overflow = true;
}
value = a * b;
}
public:
SafeInt64() {}
SafeInt64(int64_t v, bool o=false){
value = v;
overflow = o;
}
SafeInt64 operator+=(SafeInt64 b){
this->safe_add(b.value);
this->overflow |= b.overflow;
return (*this);
}
SafeInt64 operator+(SafeInt64 b){
SafeInt64 c = (*this);
c += b;
return c;
}
SafeInt64 operator*=(SafeInt64 b){
this->safe_mul(b.value);
this->overflow |= b.overflow;
return (*this);
}
SafeInt64 operator+(SafeInt64 b){
SafeInt64 c = (*this);
c *= b;
return c;
}
}
ostream& operator << (ostream& os, const SafeInt64& i){
os << i.value;
return os;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment