#include "safe_int.h" #include using namespace std; void safe_int::add_pos(int i) // i must be positive { if (value > 0 && i > numeric_limits::max() - value) { throw overflow(); } value += i; } void safe_int::add_neg(int i) // i must be negative { if (value < 0 && i < numeric_limits::min() - value) { throw underflow(); } value += i; } int safe_int::sign(int i) const { if (i < 0) { return -1; } else if (i == 0) { return 0; } else { return 1; } } safe_int::safe_int(int v) : value(v) { } safe_int::operator int() const { return value; } safe_int safe_int::operator+() { return *this; } safe_int safe_int::operator-() { return safe_int(-value); } safe_int& safe_int::operator+=(const safe_int& i) { if (i < 0) { add_neg(i); } else if (i > 0) { add_pos(i); } return *this; } safe_int& safe_int::operator-=(const safe_int& i) { if (i < 0) { add_pos(-i.value); } else if (i > 0) { add_neg(-i.value); } return *this; } safe_int& safe_int::operator*=(const safe_int& i) { int calc = value * i.value; if (i.value != 0 && calc / i.value != value) { if (sign(value) * sign(i.value) > 0) { throw overflow(); } else // < 0, cannot be zero { throw underflow(); } } else { value = calc; return *this; } } safe_int& safe_int::operator/=(const safe_int& i) { if (i.value == 0) { throw divide_by_zero(); } else { value /= i.value; return *this; } } safe_int safe_int::operator+(const safe_int& i) const { safe_int ret = *this; ret += i; return ret; } safe_int safe_int::operator-(const safe_int& i) const { safe_int ret = *this; ret -= i; return ret; } safe_int safe_int::operator*(const safe_int& i) const { safe_int ret = *this; ret *= i; return ret; } safe_int safe_int::operator/(const safe_int& i) const { safe_int ret = *this; ret *= i; return ret; }