From 3269f29dd9d1585c46b80daafd152b925b389a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 3 Sep 2018 11:37:24 +0200 Subject: [PATCH] [poincare] Integer are not Numbers anymore --- poincare/src/number.cpp | 65 +++++++++++++---------------------------- 1 file changed, 20 insertions(+), 45 deletions(-) diff --git a/poincare/src/number.cpp b/poincare/src/number.cpp index 6b8f778d5..81e936ea7 100644 --- a/poincare/src/number.cpp +++ b/poincare/src/number.cpp @@ -29,8 +29,6 @@ double NumberNode::doubleApproximation() const { } case Type::Rational: return static_cast(this)->templatedApproximate(); - case Type::Integer: - return static_cast(this)->templatedApproximate(); default: assert(false); return 0.0; @@ -38,6 +36,7 @@ double NumberNode::doubleApproximation() const { } Number Number::ParseDigits(const char * digits, size_t length) { + assert(digits[0] != '-'); const char * integral = digits; size_t integralLength = length; const char * fractional = strchr(digits, '.'); @@ -59,25 +58,25 @@ Number Number::ParseDigits(const char * digits, size_t length) { if (exponentLength == 0 && fractionalLength == 0) { Integer i(digits, length, false); if (!i.isInfinity()) { - return i; + return Rational(i); } } + int exp; // Avoid overflowing int - if (exponentLength > Decimal::k_maxExponentLength) { + if (exponentLength < Decimal::k_maxExponentLength) { + exp = Decimal::Exponent(integral, integralLength, fractional, fractionalLength, exponent, exponentLength); + } else { assert(exponent); - if (exponent[0] == '-') { + exp = exponent[0] == '-' ? -1 : 1; + } + // Avoid Decimal with exponent > k_maxExponentLength + if (exponentLength > Decimal::k_maxExponentLength || exp > Decimal::k_maxExponent || exp < -Decimal::k_maxExponent) { + if (exp < 0) { return Decimal(0.0); } else { return Infinity(false); } } - // Avoid Decimal with exponent > k_maxExponentLength - int exp = Decimal::Exponent(integral, integralLength, fractional, fractionalLength, exponent, exponentLength); - if (exp > Decimal::k_maxExponent) { - return Infinity(false); - } else if (exp < -Decimal::k_maxExponent) { - return Decimal(0.0); - } return Decimal(integral, integralLength, fractional, fractionalLength, exp); } @@ -102,49 +101,34 @@ Number Number::FloatNumber(double d) { } } -Number Number::BinaryOperation(const Number & i, const Number & j, IntegerBinaryOperation integerOp, RationalBinaryOperation rationalOp, DoubleBinaryOperation doubleOp) { - if (i.node()->type() == ExpressionNode::Type::Integer && j.node()->type() == ExpressionNode::Type::Integer) { - // Integer + Integer - Integer k = integerOp(static_cast(i), static_cast(j)); - if (!k.isInfinity()) { - return k; - } - } else if (i.node()->type() == ExpressionNode::Type::Integer && j.node()->type() == ExpressionNode::Type::Rational) { - // Integer + Rational - Rational r = rationalOp(Rational(static_cast(i)), static_cast(j)); - if (!r.numeratorOrDenominatorIsInfinity()) { - return r; - } - } else if (i.node()->type() == ExpressionNode::Type::Rational && j.node()->type() == ExpressionNode::Type::Integer) { - // Rational + Integer - return Number::BinaryOperation(j, i, integerOp, rationalOp, doubleOp); - } else if (i.node()->type() == ExpressionNode::Type::Rational && j.node()->type() == ExpressionNode::Type::Rational) { +Number Number::BinaryOperation(const Number & i, const Number & j, RationalBinaryOperation rationalOp, DoubleBinaryOperation doubleOp) { + if (i.node()->type() == ExpressionNode::Type::Rational && j.node()->type() == ExpressionNode::Type::Rational) { // Rational + Rational Rational a = rationalOp(Rational(static_cast(i)), Rational(static_cast(j))); if (!a.numeratorOrDenominatorIsInfinity()) { return a; } } - // one of the operand is Undefined/Infinity/Float or the Integer/Rational addition overflowed + // one of the operand is Undefined/Infinity/Float or the Rational addition overflowed double a = doubleOp(i.node()->doubleApproximation(), j.node()->doubleApproximation()); return FloatNumber(a); } Number Number::Addition(const Number & i, const Number & j) { - return BinaryOperation(i, j, Integer::Addition, Rational::Addition, [](double a, double b) { return a+b; }); + return BinaryOperation(i, j, Rational::Addition, [](double a, double b) { return a+b; }); } Number Number::Multiplication(const Number & i, const Number & j) { - return BinaryOperation(i, j, Integer::Multiplication, Rational::Multiplication, [](double a, double b) { return a*b; }); + return BinaryOperation(i, j, Rational::Multiplication, [](double a, double b) { return a*b; }); } Number Number::Power(const Number & i, const Number & j) { - return BinaryOperation(i, j, Integer::Power, + return BinaryOperation(i, j, // Special case for Rational^Rational: we escape to Float if the index is not an Integer [](const Rational & i, const Rational & j) { if (!j.integerDenominator().isOne()) { // We return an overflown result to reach the escape case Float+Float - return Rational(Integer::Overflow()); + return Rational(Integer::Overflow(false)); } return Rational::IntegerPower(i, j.signedIntegerNumerator()); }, @@ -155,20 +139,11 @@ Number Number::Power(const Number & i, const Number & j) { } int Number::NaturalOrder(const Number & i, const Number & j) { - if (i.node()->type() == ExpressionNode::Type::Integer && j.node()->type() == ExpressionNode::Type::Integer) { - // Integer + Integer - return Integer::NaturalOrder(static_cast(i), static_cast(j)); - } else if (i.node()->type() == ExpressionNode::Type::Integer && j.node()->type() == ExpressionNode::Type::Rational) { - // Integer + Rational - return Rational::NaturalOrder(Rational(static_cast(i)), static_cast(j)); - } else if (i.node()->type() == ExpressionNode::Type::Rational && j.node()->type() == ExpressionNode::Type::Integer) { - // Rational + Integer - return -Number::NaturalOrder(j, i); - } else if (i.node()->type() == ExpressionNode::Type::Rational && j.node()->type() == ExpressionNode::Type::Rational) { + if (i.node()->type() == ExpressionNode::Type::Rational && j.node()->type() == ExpressionNode::Type::Rational) { // Rational + Rational return Rational::NaturalOrder(static_cast(i), static_cast(j)); } - // one of the operand is Undefined/Infinity/Float or the Integer/Rational addition overflowed + // one of the operand is Undefined/Infinity/Float or the Rational addition overflowed if (i.node()->doubleApproximation() < j.node()->doubleApproximation()) { return -1; } else if (i.node()->doubleApproximation() == j.node()->doubleApproximation()) {