From 74fc7c1f58ed740b0d2407324e53a2ed03c71e10 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 24 Aug 2017 13:44:32 +0200 Subject: [PATCH] Fix real construction from long doubles. It was hard to avoid some of the compiler optimisations caused by our intermediate conversion to double, so we hide them behind the actual real object. Also, this commit fixes a potential exponent overflow. --- src/math/real.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/math/real.cpp b/src/math/real.cpp index 6a207cf0..a0c848bc 100644 --- a/src/math/real.cpp +++ b/src/math/real.cpp @@ -127,12 +127,13 @@ template<> real::Real(double d) template<> real::Real(long double f) { - /* We don’t know the long double layout, so we split it into - * two doubles instead. */ - double hi = double(f); - double lo = double(f - (long double)hi);; - new(this) real(hi); - *this += lo; + /* We don’t know the long double layout, so we get rid of the + * exponent, then load it into a real in two steps. */ + int exponent; + f = frexpl(f, &exponent); + new(this) real(double(f)); + *this += double(f - (long double)*this); + m_exponent += exponent; } template<> real::operator float() const { return (float)(double)(*this); }