//! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs int compare(const int_adapter& rhs)const { if(this->is_special() || rhs.is_special()) { if(this->is_nan() || rhs.is_nan()) { if(this->is_nan() && rhs.is_nan()) { return 0; // equal } else { return 2; // nan } } if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) || (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) ) { return -1; // less than } if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) || (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) { return 1; // greater than } } if(value_ < rhs.value_) return -1; if(value_ > rhs.value_) return 1; // implied-> if(value_ == rhs.value_) return 0; }
inline int_adapter operator-(const int_adapter<rhs_type>& rhs)const { if(is_special() || rhs.is_special()) { if (is_nan() || rhs.is_nan()) { return int_adapter::not_a_number(); } if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) || (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ) { return int_adapter::not_a_number(); } if (is_infinity()) { return *this; } if (rhs.is_pos_inf(rhs.as_number())) { return int_adapter::neg_infinity(); } if (rhs.is_neg_inf(rhs.as_number())) { return int_adapter::pos_infinity(); } } return int_adapter<int_type>(value_ - rhs.as_number()); }
int_adapter operator-(const int_adapter& rhs) const { if (is_nan() || rhs.is_nan()) { return int_adapter<int_type>(not_a_number()); } if (is_infinity()) { return *this; } if (rhs.is_infinity()) { return rhs; } return int_adapter<int_type>(value_ - rhs.value_); }
// should templatize this to be consistant with op +- int_adapter operator*(const int_adapter& rhs)const { if(this->is_special() || rhs.is_special()) { return mult_div_specials(rhs); } return int_adapter<int_type>(value_ * rhs.value_); }
// should templatize this to be consistant with op +- int_adapter operator%(const int_adapter& rhs)const { if(this->is_special() || rhs.is_special()) { if(is_infinity() && rhs.is_infinity()) { return int_adapter<int_type>(not_a_number()); } if(rhs != 0) { return mult_div_specials(rhs); } else { // let divide by zero blow itself up return int_adapter<int_type>(value_ % rhs.value_); } } return int_adapter<int_type>(value_ % rhs.value_); }
//! Assumes at least 'this' or 'rhs' is a special value int_adapter mult_div_specials(const int_adapter& rhs)const { int min_value; // quiets compiler warnings bool is_signed = std::numeric_limits<int_type>::is_signed; if(is_signed) { min_value = 0; } else { min_value = 1;// there is no zero with unsigned } if(this->is_nan() || rhs.is_nan()) { return int_adapter<int_type>(not_a_number()); } if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) { return int_adapter<int_type>(pos_infinity()); } if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) { return int_adapter<int_type>(neg_infinity()); } //implied -> if(this->value_ == 0 || rhs.value_ == 0) return int_adapter<int_type>(not_a_number()); }