Last active
June 6, 2018 10:08
-
-
Save zaburo-ch/5b6939eef9bc022dfa1e8140be6558dd to your computer and use it in GitHub Desktop.
[WIP] C++ int64_t overflow detection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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