[poincare] Fix constructors of Integer, Rational and Decimal

This commit is contained in:
Émilie Feral
2018-08-13 14:50:24 +02:00
parent 4dd48139c0
commit 22aa86bc61
5 changed files with 41 additions and 35 deletions

View File

@@ -95,10 +95,7 @@ public:
private:
DecimalNode * node() const override { return static_cast<DecimalNode *>(Number::node()); }
template <typename T> Decimal(T f);
Decimal(size_t size) : Number(nullptr) {
TreeNode * node = TreePool::sharedPool()->createTreeNode<DecimalNode>(size);
TreeByReference::setIdentifierAndRetain(node->identifier());
}
Decimal(size_t size, Integer m, int e);
// Simplification
Expression shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const;
Expression shallowBeautify(Context& context, Preferences::AngleUnit angleUnit) const;

View File

@@ -123,11 +123,9 @@ Expression ComplexNode<T>::complexToExpression(Preferences::ComplexFormat comple
template<typename T>
Complex<T>::Complex(std::complex<T> c) :
Evaluation<T>()
Evaluation<T>(TreePool::sharedPool()->createTreeNode<ComplexNode<T>>())
{
TreeNode * node = TreePool::sharedPool()->createTreeNode<ComplexNode<T>>();
TreeByReference::setIdentifierAndRetain(node->identifier());
static_cast<ComplexNode<T> *>(node)->setComplex(c);
static_cast<ComplexNode<T> *>(this->node())->setComplex(c);
}
template class ComplexNode<float>;

View File

@@ -249,7 +249,7 @@ Decimal::Decimal(const char * integralPart, int integralPartLength, const char *
numerator = Integer::Addition(numerator, Integer(*fractionalPart-'0'));
fractionalPart++;
}
*this = Decimal(numerator, exponent);
new (this) Decimal(numerator, exponent);
}
template <typename T>
@@ -258,11 +258,16 @@ Decimal::Decimal(T f) : Number(nullptr) {
int exp = IEEE754<T>::exponentBase10(f);
int64_t mantissaf = std::round((double)f * std::pow((double)10.0, (double)(-exp+PrintFloat::k_numberOfStoredSignificantDigits+1)));
Integer m(mantissaf);
*this= Decimal(Integer(mantissaf), exp);
new (this) Decimal(Integer(mantissaf), exp);
}
Decimal::Decimal(Integer m, int e) {
*this = Decimal(sizeof(DecimalNode)+sizeof(native_uint_t)*m.numberOfDigits());
size_t s = sizeof(DecimalNode);
s += m.isInfinity() ? 0 : sizeof(native_uint_t)*m.numberOfDigits();
new (this) Decimal(s, m, e);
}
Decimal::Decimal(size_t size, Integer m, int e) : Number(TreePool::sharedPool()->createTreeNode<DecimalNode>(size)) {
node()->setValue(m.node()->digits(), m.node()->numberOfDigits(), e, m.isNegative());
}

View File

@@ -444,7 +444,9 @@ Integer::Integer(size_t size, const native_uint_t * digits, size_t numberOfDigit
Integer::Integer(const native_uint_t * digits, size_t numberOfDigits, bool negative) :
Integer(numberOfDigits*sizeof(native_uint_t)+sizeof(IntegerNode), digits, numberOfDigits, negative)
{}
{
assert(numberOfDigits <= NaturalIntegerAbstract::k_maxNumberOfDigits);
}
Integer::Integer(const char * digits, size_t length, bool negative) :
Number(nullptr)
@@ -464,7 +466,7 @@ Integer::Integer(const char * digits, size_t length, bool negative) :
d = 0;
}
if (size >= NaturalIntegerAbstract::k_maxNumberOfDigits) {
*this = Integer::Overflow();
*this = Overflow();
return;
}
d = 10*d+(*digits-'0');
@@ -472,7 +474,7 @@ Integer::Integer(const char * digits, size_t length, bool negative) :
}
}
buffer[size++] = d;
*this = Integer(buffer, size, negative);
new (this) Integer(buffer, size, negative);
}
Integer::Integer(const NaturalIntegerAbstract * naturalInteger) :
@@ -484,19 +486,19 @@ Integer::Integer(native_int_t i) :
Number(nullptr)
{
if (i == 0) {
*this = Integer((const native_uint_t *)nullptr, 0, false);
new (this) Integer((const native_uint_t *)nullptr, 0, false);
return;
}
native_uint_t digits[1];
digits[0] = i < 0 ? -i : i;
*this = Integer(digits, 1, i < 0);
new (this) Integer(digits, 1, i < 0);
}
Integer::Integer(double_native_int_t i) :
Number(nullptr)
{
if (i == 0) {
*this = Integer((const native_uint_t *)nullptr, 0, false);
new (this) Integer((const native_uint_t *)nullptr, 0, false);
return;
}
double_native_uint_t j = i < 0 ? -i : i;
@@ -505,10 +507,10 @@ Integer::Integer(double_native_int_t i) :
native_uint_t mostSignificantDigit = *(digits+1);
native_uint_t digitsArray[2] = {leastSignificantDigit, mostSignificantDigit};
if (mostSignificantDigit == 0) {
*this = Integer(digitsArray, 1, i < 0);
new (this) Integer(digitsArray, 1, i < 0);
return;
}
*this = Integer(digitsArray, 2, i < 0);
new (this) Integer(digitsArray, 2, i < 0);
}
int Integer::extractedInt() const {

View File

@@ -19,8 +19,12 @@ void RationalNode::setDigits(native_uint_t * numeratorDigits, size_t numeratorSi
m_numberOfDigitsNumerator = numeratorSize;
m_numberOfDigitsDenominator = denominatorSize;
size_t numeratorCopySize = numeratorSize*sizeof(native_uint_t);
memcpy(m_digits, numeratorDigits, numeratorCopySize);
memcpy(m_digits + numeratorCopySize, denominatorDigits, denominatorSize*sizeof(native_uint_t));
if (numeratorDigits) {
memcpy(m_digits, numeratorDigits, numeratorCopySize);
}
if (denominatorDigits) {
memcpy(m_digits + numeratorCopySize, denominatorDigits, denominatorSize*sizeof(native_uint_t));
}
}
RationalNode * RationalNode::FailedAllocationStaticNode() {
@@ -154,42 +158,44 @@ Rational::Rational(Integer numerator, Integer denominator) :
denominator = Integer::Division(denominator, gcd).quotient;
}
if (numerator.node()->isAllocationFailure() || denominator.node()->isAllocationFailure()) {
*this = Rational(RationalNode::FailedAllocationStaticNode());
new (this) Rational(RationalNode::FailedAllocationStaticNode());
return;
}
bool negative = (numerator.sign() == ExpressionNode::Sign::Positive && denominator.sign() == ExpressionNode::Sign::Negative) || (denominator.sign() == ExpressionNode::Sign::Positive && numerator.sign() == ExpressionNode::Sign::Negative);
*this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*(numerator.node()->numberOfDigits()+denominator.node()->numberOfDigits()), numerator.node()->digits(), numerator.node()->numberOfDigits(), denominator.node()->digits(), denominator.node()->numberOfDigits(), negative);
return;
size_t size = sizeof(RationalNode);
size += numerator.isInfinity() ? 0 : sizeof(native_uint_t)*numerator.node()->numberOfDigits();
size += denominator.isInfinity() ? 0 : sizeof(native_uint_t)*denominator.node()->numberOfDigits();
new (this) Rational(size, numerator.node()->digits(), numerator.node()->numberOfDigits(), denominator.node()->digits(), denominator.node()->numberOfDigits(), negative);
}
Rational::Rational(const Integer numerator) :
Number(nullptr)
{
if (numerator.node()->isAllocationFailure()) {
*this = Rational(RationalNode::FailedAllocationStaticNode());
new (this) Rational(RationalNode::FailedAllocationStaticNode());
}
*this = Rational(numerator.node(), numerator.sign() == ExpressionNode::Sign::Negative);
new (this) Rational(numerator.node(), numerator.sign() == ExpressionNode::Sign::Negative);
}
Rational::Rational(const NaturalIntegerAbstract * numerator, bool negative) : Number(nullptr) {
native_uint_t one = 1;
*this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*(numerator->numberOfDigits()+1), numerator->digits(), numerator->numberOfDigits(), &one, 1, negative);
size_t size = sizeof(RationalNode) + sizeof(native_uint_t);
size += numerator->isInfinity() ? sizeof(native_uint_t)*numerator->numberOfDigits() : 0;
new (this) Rational(size, numerator->digits(), numerator->numberOfDigits(), &one, 1, negative);
return;
}
Rational::Rational(native_int_t i) : Number(nullptr) {
native_uint_t absI = i < 0 ? -i : i;
native_uint_t one = 1;
*this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2, &absI, 1, &one, 1, i < 0);
return;
new (this) Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2, &absI, 1, &one, 1, i < 0);
}
Rational::Rational(native_int_t i, native_int_t j) : Number(nullptr) {
assert(j != 0);
native_uint_t absI = i < 0 ? -i : i;
native_uint_t absJ = j < 0 ? -j : j;
*this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2, &absI, 1, &absJ, 1, (i < 0 && j > 0) || (i > 0 && j < 0));
return;
new (this) Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2, &absI, 1, &absJ, 1, (i < 0 && j > 0) || (i > 0 && j < 0));
}
bool Rational::numeratorOrDenominatorIsInfinity() const {
@@ -236,12 +242,10 @@ Rational Rational::IntegerPower(const Rational i, const Rational j) {
}
Rational::Rational(size_t size, native_uint_t * i, size_t numeratorSize, native_uint_t * j, size_t denominatorSize, bool negative) :
Number(nullptr)
Number(TreePool::sharedPool()->createTreeNode<RationalNode>(size))
{
assert(j != 0);
TreeNode * node = TreePool::sharedPool()->createTreeNode<RationalNode>(size);
TreeByReference::setIdentifierAndRetain(node->identifier());
static_cast<RationalNode *>(node)->setDigits(i, numeratorSize, j, denominatorSize, negative);
static_cast<RationalNode *>(node())->setDigits(i, numeratorSize, j, denominatorSize, negative);
}
Expression Rational::shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) const {