inline void convert(const mpz_class& v1, long int& v2) { // TODO: Better precision exception information. if (!v1.fits_slong_p()) { throw PrecisionException(0); } v2 = v1.get_si(); }
inline void convert(const _4ti2_int64_t& v1, _4ti2_int32_t& v2) { // TODO: Better precision exception information. if (v1 < INT32_MIN || v2 > INT32_MAX) { throw PrecisionException(32); } v2 = v1; }
Estimate recip(const Estimate &arg) { if (!arg.IsNonZero()) throw PrecisionException("recip"); LongFloat r(arg.m_Value.recip()); ErrorEstimate e(arg.m_Value, ErrorEstimate::Down); ErrorEstimate re(RoundingError(r, r.DivisionRoundingError())); return Estimate(r, (arg.m_Error / (e - arg.m_Error) / e) + re); // multiplication in denominator would have the wrong rounding mode }
Estimate operator / (const Estimate &lhs, const Estimate &rhs) { if (!rhs.IsNonZero()) throw PrecisionException("division"); // this also assures e - rhs.m_Error > 0 LongFloat r(lhs.m_Value / rhs.m_Value); ErrorEstimate e(rhs.m_Value, ErrorEstimate::Down); ErrorEstimate n(ErrorEstimate(lhs.m_Value) * rhs.m_Error + ErrorEstimate(rhs.m_Value, ErrorEstimate::Up) * lhs.m_Error); return Estimate(r, n / (e - rhs.m_Error) / e + RoundingError(r, r.DivisionRoundingError())); // multiplication in denominator would have the wrong rounding mode }