imprecise.cpp (1173B)
1 #include <iostream> 2 #include <stdexcept> 3 4 int sign(int x) noexcept 5 { 6 return x < 0 ? -1 : !!x; 7 } 8 9 struct imprecise 10 { 11 imprecise(int l, int h) 12 : low{l} 13 , high{h} 14 { 15 if (l > h) 16 throw std::domain_error{"imprecise: low > high"}; 17 } 18 19 imprecise operator +(imprecise rhs) const noexcept 20 { 21 return {low + rhs.low, high + rhs.high}; 22 } 23 24 imprecise operator *(imprecise rhs) const noexcept 25 { 26 int h = high * rhs.high; 27 int l = low * rhs.low; 28 if (h > l) 29 return {l, h}; 30 return {h, l}; 31 } 32 33 imprecise square() const noexcept 34 { 35 if (sign(low) == sign(high)) 36 return *this * *this; 37 return {0, std::max(low*low, high*high)}; 38 } 39 bool operator ==(imprecise const& rhs) const = default; 40 bool operator !=(imprecise const& rhs) const = default; 41 42 private: 43 int low, high; 44 friend std::ostream& operator <<(std::ostream& os, imprecise rhs); 45 }; 46 47 std::ostream& operator <<(std::ostream& os, imprecise rhs) 48 { 49 return os << rhs.low << ".." << rhs.high; 50 } 51 52 int main() 53 { 54 std::cout << imprecise{-1,1} + imprecise{-1,1} << '\n'; 55 std::cout << imprecise{1,2}.square() << '\n'; 56 std::cout << imprecise{-2,-1}.square() << '\n'; 57 std::cout << imprecise{-1,1}.square() << '\n'; 58 }