[poincare] Number: add a new constructor to parse Number

This commit is contained in:
Émilie Feral
2018-09-20 16:53:54 +02:00
parent 8d203aaf48
commit 2b87c735d3
4 changed files with 30 additions and 4 deletions

View File

@@ -86,7 +86,7 @@ class Decimal final : public Number {
friend class Number;
friend class DecimalNode;
public:
static int Exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength);
static int Exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength, bool exponentIsNegative = false);
Decimal(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, int exponent);
Decimal(DecimalNode * node) : Number(node) {}
Decimal(Integer m, int e);

View File

@@ -27,7 +27,8 @@ class Number : public Expression {
public:
Number(const NumberNode * node) : Expression(node) {}
/* Return either a Rational, a Decimal or an Infinity. */
static Number ParseDigits(const char * digits, size_t length);
static Number ParseDigits(const char * digits, size_t length); // TODO: remove me when homemade parser is ready
static Number ParseNumber(const char * integralPart, size_t integralLength, const char * decimalPart, size_t decimalLenght, bool exponentIsNegative, const char * exponentPart, size_t exponentLength);
/* Return either a Decimal or an Infinity or an Undefined. */
template <typename T> static Number DecimalNumber(T f);
/* Return either a Float or an Infinity or an Undefined */

View File

@@ -220,8 +220,7 @@ template<typename T> T DecimalNode::templatedApproximate() const {
return f*std::pow((T)10.0, (T)(m_exponent-numberOfDigits+1));
}
int Decimal::Exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength) {
bool exponentNegative = false;
int Decimal::Exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength, bool exponentNegative) {
if (exponentLength > 0 && exponent[0] == '-') {
exponent++;
exponentNegative = true;

View File

@@ -80,6 +80,32 @@ Number Number::ParseDigits(const char * digits, size_t length) {
return Decimal(integral, integralLength, fractional, fractionalLength, exp);
}
Number Number::ParseNumber(const char * integralPart, size_t integralLength, const char * decimalPart, size_t decimalLenght, bool exponentIsNegative, const char * exponentPart, size_t exponentLength) {
// Integer
if (exponentLength == 0 && decimalLenght == 0) {
Integer i(integralPart, integralLength, false);
if (!i.isInfinity()) {
return Rational(i);
}
}
int exp;
// Avoid overflowing int
if (exponentLength < Decimal::k_maxExponentLength) {
exp = Decimal::Exponent(integralPart, integralLength, decimalPart, decimalLenght, exponentPart, exponentLength, exponentIsNegative);
} else {
exp = exponentIsNegative ? -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);
}
}
return Decimal(integralPart, integralLength, decimalPart, decimalLenght, exp);
}
template <typename T>
Number Number::DecimalNumber(T f) {
if (std::isnan(f)) {