#ifndef __SAFEOPS_H__ #define __SAFEOPS_H__ #include #include "gcd.h" // Here's how I approach the problem of dealing with overflow. // // I don't want to completely rewrite my fraction.cpp code to contain // calls to functions like "safeAdd" and "safeMultiply". Instead, I'd // rather keep fraction.cpp looking as much like normal math as possible, // and abstract the idea of overflow into a separate module. That // inspired the notion of creating a class which wraps integers but also // maintains an overflow bit. If that class has the normal arithmetic // operators associated with it, I can simply pretend in fraction.cpp // that SafeInt's are int's, and everything should work the same. class SafeInt { public: SafeInt() : num( 0 ) , valid( false ) {} SafeInt( int x ) : num( x ) , valid( true ) {} bool operator ==( SafeInt other ) { return (valid == other.valid) && (num == other.num); } bool operator !=( SafeInt other ) { return !( (*this) == other ); } bool operator <( SafeInt other ) { return (valid && other.valid) ? (num < other.num) : false; } SafeInt operator +( SafeInt other ); SafeInt operator *( SafeInt other ); SafeInt operator /( SafeInt other ); SafeInt operator -() { return good() ? SafeInt( -num ) : SafeInt(); } SafeInt& operator /=( SafeInt other ) { return (*this) = (*this) / other; } bool good() { return valid; } int getValue() { return num; } private: int num; bool valid; }; // Out-of-class operations that you can do on SafeInts. Some of these // are chosen to match up exactly with the functions that are available // in GNU's Integer.h. // Just call the GreatestCommonDivisor function SafeInt gcd( SafeInt a, SafeInt b ); // Return -1, 0 or +1 depending on whether a<0, a==0 or a>0 int sign( SafeInt a ); // Return (double)a/(double)b double ratio( SafeInt a, SafeInt b ); // Do one integer division bool divide( SafeInt a, SafeInt b, SafeInt& q, SafeInt& r ); // Is m a number? bool good( SafeInt& m ); // Print SafeInts. ostream& operator <<( ostream& os, SafeInt& si ); #endif // __SAFEOPS_H__