diff --git a/poincare/include/poincare/randint.h b/poincare/include/poincare/randint.h index 78032a260..62870714e 100644 --- a/poincare/include/poincare/randint.h +++ b/poincare/include/poincare/randint.h @@ -6,6 +6,7 @@ namespace Poincare { class RandintNode /*final*/ : public ExpressionNode { + friend class Randint; public: // TreeNode @@ -33,7 +34,7 @@ private: Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templateApproximate(context, complexFormat, angleUnit); } - template Evaluation templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + template Evaluation templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool * inputIsUndefined = nullptr) const; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; }; diff --git a/poincare/src/randint.cpp b/poincare/src/randint.cpp index e3f284ed2..f71076786 100644 --- a/poincare/src/randint.cpp +++ b/poincare/src/randint.cpp @@ -28,9 +28,12 @@ int RandintNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloa return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Randint::s_functionHelper.name()); } -template Evaluation RandintNode::templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { +template Evaluation RandintNode::templateApproximate(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, bool * inputIsUndefined) const { Evaluation aInput = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); Evaluation bInput = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); + if (inputIsUndefined) { + *inputIsUndefined = aInput.isUndefined() || bInput.isUndefined(); + } T a = aInput.toScalar(); T b = bInput.toScalar(); if (std::isnan(a) || std::isnan(b) || a != std::round(a) || b != std::round(b) || a > b || std::isinf(a) || std::isinf(b)) { @@ -49,9 +52,10 @@ Expression Randint::shallowReduce(ExpressionNode::ReductionContext reductionCont if (e.isUndefined()) { return e; } - double eval = approximateToScalar(reductionContext.context() , reductionContext.complexFormat() , reductionContext.angleUnit() ); - if (std::isnan(eval)) { - /* The result might be NAN because we are reducing a function's expression + bool inputIsUndefined = false; + double eval = static_cast(node())->templateApproximate(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit(), &inputIsUndefined).toScalar(); + if (inputIsUndefined) { + /* The input might be NAN because we are reducing a function's expression * which depends on x. We thus do not want to replace too early with * undefined. */ return *this;