[poincare] Create a method Number::Decimal which build a Decimal or a

Infinite when overflowing
This commit is contained in:
Émilie Feral
2018-08-03 16:43:21 +02:00
parent 2c5c14f0ab
commit 152ef8a8df
3 changed files with 21 additions and 19 deletions

View File

@@ -31,6 +31,8 @@ public:
NumberNode * numberNode() const { assert(!isAllocationFailure()); return static_cast<NumberNode *>(node()); }
/* Return either a IntegerReference, a DecimalReference or an InfiniteReference. */
static NumberReference Integer(const char * digits, size_t length, bool negative);
/* Return either a DecimalInteger or an InfiniteReference. */
template <typename T> static NumberReference Decimal(T f);
/* This set of Functions return either a RationalReference or a FloatReference
* or InfiniteReference in case of overflow. DecimalReference are not taken into
* account as it is not an internal node - it will always be turned into a

View File

@@ -42,17 +42,6 @@ T ComplexNode<T>::toScalar() const {
return NAN;
}
template <typename T>
static ExpressionReference CreateDecimal(T f) {
if (std::isnan(f)) {
return UndefinedReference();
}
if (std::isinf(f)) {
return InfiniteReference(f < 0.0);
}
return DecimalReference(f);
}
template<typename T>
ExpressionReference ComplexNode<T>::complexToExpression(Preferences::ComplexFormat complexFormat) const {
if (std::isnan(this->real()) || std::isnan(this->imag())) {
@@ -64,15 +53,15 @@ ExpressionReference ComplexNode<T>::complexToExpression(Preferences::ComplexForm
ExpressionReference real(nullptr);
ExpressionReference imag(nullptr);
if (this->real() != 0 || this->imag() == 0) {
real = CreateDecimal<T>(this->real());
real = NumberReference::Decimal<T>(this->real());
}
if (this->imag() != 0) {
if (this->imag() == 1.0 || this->imag() == -1) {
imag = SymbolReference(Ion::Charset::IComplex);
} else if (this->imag() > 0) {
imag = MultiplicationReference(CreateDecimal(this->imag()), SymbolReference(Ion::Charset::IComplex));
imag = MultiplicationReference(NumberReference::Decimal(this->imag()), SymbolReference(Ion::Charset::IComplex));
} else {
imag = MultiplicationReference(CreateDecimal(-this->imag()), SymbolReference(Ion::Charset::IComplex));
imag = MultiplicationReference(NumberReference::Decimal(-this->imag()), SymbolReference(Ion::Charset::IComplex));
}
}
if (!imag.isDefined()) {
@@ -98,7 +87,7 @@ ExpressionReference ComplexNode<T>::complexToExpression(Preferences::ComplexForm
T r = std::abs(*this);
T th = std::arg(*this);
if (r != 1 || th == 0) {
norm = CreateDecimal(r);
norm = NumberReference::Decimal(r);
}
if (r != 0 && th != 0) {
ExpressionReference arg(nullptr);
@@ -107,9 +96,9 @@ ExpressionReference ComplexNode<T>::complexToExpression(Preferences::ComplexForm
} else if (th == -1.0) {
arg = OppositeReference(SymbolReference(Ion::Charset::IComplex));
} else if (th > 0) {
arg = MultiplicationReference(CreateDecimal(th), SymbolReference(Ion::Charset::IComplex));
arg = MultiplicationReference(NumberReference::Decimal(th), SymbolReference(Ion::Charset::IComplex));
} else {
arg = OppositeRefrence(MultiplicationReference(CreateDecimal(-th), SymbolReference(Ion::Charset::IComplex)));
arg = OppositeRefrence(MultiplicationReference(NumberReference::Decimal(-th), SymbolReference(Ion::Charset::IComplex)));
}
exp = PowerReference(SymbolReference(Ion::Charset::Exponential), arg);
}

View File

@@ -1,4 +1,5 @@
#include <poincare/number.h>
#include <poincare/decimal.h>
#include <poincare/integer.h>
#include <poincare/rational.h>
#include <poincare/float.h>
@@ -55,11 +56,21 @@ NumberReference NumberReference::Integer(const char * digits, size_t length, boo
negative = true;
digits++;
}
/*if (length > Decimal::k_maxExponentLength) {
if (length > Decimal::k_maxExponentLength) {
return InfinityReference(negative);
}
int exponent = Decimal::Exponent(digits, length, nullptr, 0, nullptr, 0, negative);
return DecimalReference(digits, length, nullptr, 0, negative, exponent);*/
return DecimalReference(digits, length, nullptr, 0, negative, exponent);
}
template <typename T> static NumberReference NumberReference::Decimal(T f) {
if (std::isnan(f)) {
return UndefinedReference();
}
if (std::isinf(f)) {
return InfiniteReference(f < 0.0);
}
return DecimalReference(f);
}
NumberReference NumberReference::BinaryOperation(const NumberReference i, const NumberReference j, IntegerBinaryOperation integerOp, RationalBinaryOperation rationalOp, DoubleBinaryOperation doubleOp) {