From cf84a307680029fdfd1cbb2f4bf0791d9cf54f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 4 Mar 2020 10:17:00 +0100 Subject: [PATCH] [poincare/absolute_value] ShallowReduce done in double, not float This fixes abs(-2.3*10^-39) that returned a negative value --- poincare/src/absolute_value.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index 18bbafe14..bf4aee0d1 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -50,21 +50,21 @@ Expression AbsoluteValue::shallowReduce(ExpressionNode::ReductionContext reducti } // |x| = ±x if x is real if (c.isReal(reductionContext.context())) { - float app = c.node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()).toScalar(); - if (!std::isnan(app) && - ((c.isNumber() && app >= 0) || app >= Expression::Epsilon())) { - /* abs(a) = a with a >= 0 - * To check that a > 0, if a is a number we can use float comparison; - * in other cases, we are more conservative and rather check that - * a > epsilon ~ 1E-7 to avoid potential error due to float precision. */ - replaceWithInPlace(c); - return c; - } else if (!std::isnan(app) && - ((c.isNumber() && app < 0.0f) || app <= -Expression::Epsilon())) { - // abs(a) = -a with a < 0 (same comment as above to check that a < 0) - Multiplication m = Multiplication::Builder(Rational::Builder(-1), c); - replaceWithInPlace(m); - return m.shallowReduce(reductionContext); + double app = c.node()->approximate(double(), reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()).toScalar(); + if (!std::isnan(app)) { + if ((c.isNumber() && app >= 0) || app >= Expression::Epsilon()) { + /* abs(a) = a with a >= 0 + * To check that a > 0, if a is a number we can use float comparison; + * in other cases, we are more conservative and rather check that + * a > epsilon ~ 1E-7 to avoid potential error due to float precision. */ + replaceWithInPlace(c); + return c; + } else if ((c.isNumber() && app < 0.0f) || app <= -Expression::Epsilon()) { + // abs(a) = -a with a < 0 (same comment as above to check that a < 0) + Multiplication m = Multiplication::Builder(Rational::Builder(-1), c); + replaceWithInPlace(m); + return m.shallowReduce(reductionContext); + } } } // |a+ib| = sqrt(a^2+b^2)