[poincare/multiplication] Interrupt reduction if overflow

When the overflow is due to the max size a rational can hold, stop the
reduction, otherwise some false results can appear.
For instance: 1.0092^50*ln(1.0092) was computed to 0 due to this problem
This commit is contained in:
Léa Saviot
2020-03-13 13:39:39 +01:00
committed by RubenNumworks
parent f00bd4d1c5
commit da6306cb11
2 changed files with 10 additions and 0 deletions

View File

@@ -760,6 +760,14 @@ Expression Multiplication::privateShallowReduce(ExpressionNode::ReductionContext
if (childAtIndex(0).isNumber()) {
Number o0 = childAtIndex(0).convert<Rational>();
Number m = Number::Multiplication(o0, static_cast<Number &>(o));
if ((IsInfinity(m, context) || m.isUndefined())
&& !IsInfinity(o0, context) && !o0.isUndefined()
&& !IsInfinity(o, context) && !o.isUndefined())
{
// Stop the reduction due to a multiplication overflow
SetInterruption(true);
return *this;
}
replaceChildAtIndexInPlace(0, m);
removeChildAtIndexInPlace(i);
} else {

View File

@@ -941,8 +941,10 @@ QUIZ_CASE(poincare_approximation_mix) {
assert_expression_simplifies_and_approximates_to("1.0092^(20)", "1.2010050593402");
assert_expression_simplifies_and_approximates_to("1.0092^(50)×ln(3/2)", "0.6409373488899", Degree, Cartesian, 13);
assert_expression_simplifies_and_approximates_to("1.0092^(50)×ln(1.0092)", "1.447637354655ᴇ-2", Degree, Cartesian, 13);
assert_expression_approximates_to<double>("1.0092^(20)", "1.2010050593402");
assert_expression_approximates_to<double>("1.0092^(50)×ln(3/2)", "0.6409373488899", Degree, Cartesian, 13);
assert_expression_approximates_to<double>("1.0092^(50)×ln(1.0092)", "1.447637354655ᴇ-2", Degree, Cartesian, 13);
assert_expression_simplifies_approximates_to<double>("1.0092^(20)", "1.2010050593402");
assert_expression_simplifies_approximates_to<double>("1.0092^(50)×ln(3/2)", "0.6409373488899", Degree, Cartesian, 13);
//assert_expression_approximates_to<float>("1.0092^(20)", "1.201005"); TODO does not work