diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index afc80acba..39452e2e8 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -510,36 +510,44 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu result = units; } else { double value = result.approximateToScalar(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()); - if (std::isinf(value)) { - result = Infinity::Builder(false); //FIXME sign? - } else if (std::isnan(value)) { + if (std::isnan(value)) { + // If the value is undefined, return "undef" without any unit result = Undefined::Builder(); } else { - // Identify the first Unit factor and its exponent - Expression firstFactor = units; - int exponent = 1; - if (firstFactor.type() == ExpressionNode::Type::Multiplication) { - firstFactor = firstFactor.childAtIndex(0); - } - if (firstFactor.type() == ExpressionNode::Type::Power) { - Expression exp = firstFactor.childAtIndex(1); - firstFactor = firstFactor.childAtIndex(0); - assert(exp.type() == ExpressionNode::Type::Rational && static_cast(exp).isInteger()); - Integer expInt = static_cast(exp).signedIntegerNumerator(); - if (expInt.isLowerThan(Integer(Integer::k_maxExtractableInteger))) { - exponent = expInt.extractedInt(); - } else { - // The exponent is too large to be extracted, so do not try to use it. - exponent = 0; + Expression resultWithoutUnit; + if (std::isinf(value)) { + resultWithoutUnit = Infinity::Builder(value < 0.0); + } else { + // Find the right unit prefix when the value ≠ 0 + if (value != 0.0) { + // Identify the first Unit factor and its exponent + Expression firstFactor = units; + int exponent = 1; + if (firstFactor.type() == ExpressionNode::Type::Multiplication) { + firstFactor = firstFactor.childAtIndex(0); + } + if (firstFactor.type() == ExpressionNode::Type::Power) { + Expression exp = firstFactor.childAtIndex(1); + firstFactor = firstFactor.childAtIndex(0); + assert(exp.type() == ExpressionNode::Type::Rational && static_cast(exp).isInteger()); + Integer expInt = static_cast(exp).signedIntegerNumerator(); + if (expInt.isLowerThan(Integer(Integer::k_maxExtractableInteger))) { + exponent = expInt.extractedInt(); + } else { + // The exponent is too large to be extracted, so do not try to use it. + exponent = 0; + } + } + assert(firstFactor.type() == ExpressionNode::Type::Unit); + // Choose its multiple and update value accordingly + if (exponent != 0) { + static_cast(firstFactor).chooseBestMultipleForValue(value, exponent, reductionContext); + } } - } - assert(firstFactor.type() == ExpressionNode::Type::Unit); - // Choose its multiple and update value accordingly - if (exponent != 0) { - static_cast(firstFactor).chooseBestMultipleForValue(value, exponent, reductionContext); + resultWithoutUnit = Float::Builder(value); } // Build final Expression - result = Multiplication::Builder(Float::Builder(value), units); + result = Multiplication::Builder(resultWithoutUnit, units); static_cast(result).mergeMultiplicationChildrenInPlace(); } } diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 89288f8f1..5c4c53fde 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -309,6 +309,16 @@ QUIZ_CASE(poincare_simplification_units) { assert_parsed_expression_simplify_to("_A^2×_s^4×_kg^(-1)×_m^(-3)", "_F×_m^\u0012-1\u0013"); // Vacuum magnetic permeability 𝝴0 assert_parsed_expression_simplify_to("_kg×_s^(-3)×_K^(-4)", "_K^\u0012-4\u0013×_kg×_s^\u0012-3\u0013"); // Stefan–Boltzmann constant _W×_m^-2×_K^-4 + /* Keep units for 0, infinity float results, Remove unit for undefined + * expression */ + //assert_parsed_expression_simplify_to("0_s", "0_s"); + assert_parsed_expression_simplify_to("inf×_s", "inf×_s"); + //assert_parsed_expression_simplify_to("-inf×_s", "-inf×_s"); + //assert_parsed_expression_simplify_to("2_s+3_s-5_s", "0_s"); + assert_parsed_expression_simplify_to("normcdf(0,20,3)×_s", "0×_s"); + //assert_parsed_expression_simplify_to("log(0)×_s", "-inf×_s"); + assert_parsed_expression_simplify_to("log(undef)*_s", "undef"); + /* Units with invalid exponent */ assert_parsed_expression_simplify_to("_s^(1/2)", "undef");