mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-21 23:00:45 +01:00
[poincare] Fix Integer constructor: avoid creating Integer without
setting the digits because at destruction the size() is wrong and corrupt the pool
This commit is contained in:
@@ -105,8 +105,6 @@ public:
|
||||
IntegerNode() :
|
||||
NaturalIntegerAbstract(),
|
||||
m_negative(false) {}
|
||||
virtual void setDigits(native_int_t i);
|
||||
virtual void setDigits(double_native_int_t i);
|
||||
virtual void setDigits(const native_uint_t * digits, size_t size, bool negative);
|
||||
|
||||
// Allocation Failure
|
||||
@@ -176,8 +174,6 @@ class AllocationFailureIntegerNode : public AllocationFailureExpressionNode<Inte
|
||||
public:
|
||||
// IntegerNode
|
||||
bool isZero() const override { return false; }
|
||||
void setDigits(native_int_t i) override {}
|
||||
void setDigits(double_native_int_t i) override {}
|
||||
void setDigits(const native_uint_t * digits, size_t size, bool negative) override {}
|
||||
};
|
||||
|
||||
@@ -223,8 +219,7 @@ private:
|
||||
IntegerNode * node() const override { return static_cast<IntegerNode *>(Number::node()); }
|
||||
|
||||
Integer(const native_uint_t * digits, size_t numberOfDigits, bool negative);
|
||||
Integer(size_t size) : Number(TreePool::sharedPool()->createTreeNode<IntegerNode>(size)) {
|
||||
}
|
||||
Integer(size_t size, const native_uint_t * digits, size_t numberOfDigits, bool negative);
|
||||
static Integer addition(const Integer & a, const Integer & b, bool inverseBNegative);
|
||||
size_t numberOfDigits() const { return node()->numberOfDigits(); }
|
||||
uint32_t digit(int i) const { return node()->digit(i); }
|
||||
|
||||
@@ -361,35 +361,6 @@ IntegerNode * IntegerNode::FailedAllocationStaticNode() {
|
||||
return &failure;
|
||||
}
|
||||
|
||||
void IntegerNode::setDigits(native_int_t i) {
|
||||
if (i == 0) {
|
||||
m_numberOfDigits = 0;
|
||||
m_negative = false;
|
||||
return;
|
||||
}
|
||||
m_negative = i < 0;
|
||||
m_digits[0] = i < 0 ? -i : i;
|
||||
m_numberOfDigits = 1;
|
||||
}
|
||||
|
||||
void IntegerNode::setDigits(double_native_int_t i) {
|
||||
if (i == 0) {
|
||||
m_numberOfDigits = 0;
|
||||
m_negative = false;
|
||||
return;
|
||||
}
|
||||
double_native_uint_t j = i < 0 ? -i : i;
|
||||
native_uint_t * digits = (native_uint_t *)&j;
|
||||
native_uint_t leastSignificantDigit = *digits;
|
||||
native_uint_t mostSignificantDigit = *(digits+1);
|
||||
m_numberOfDigits = (mostSignificantDigit == 0) ? 1 : 2;
|
||||
m_digits[0] = leastSignificantDigit;
|
||||
if (m_numberOfDigits > 1) {
|
||||
m_digits[1] = mostSignificantDigit;
|
||||
}
|
||||
m_negative = i < 0;
|
||||
|
||||
}
|
||||
void IntegerNode::setDigits(const native_uint_t * digits, size_t size, bool negative) {
|
||||
memcpy(m_digits, digits, size*sizeof(native_uint_t));
|
||||
m_numberOfDigits = size;
|
||||
@@ -459,15 +430,17 @@ int IntegerNode::NaturalOrder(const IntegerNode * i, const IntegerNode * j) {
|
||||
|
||||
/* Integer */
|
||||
|
||||
Integer::Integer(const native_uint_t * digits, size_t numberOfDigits, bool negative) :
|
||||
Integer(numberOfDigits*sizeof(native_uint_t)+sizeof(IntegerNode))
|
||||
{
|
||||
Integer::Integer(size_t size, const native_uint_t * digits, size_t numberOfDigits, bool negative) : Number(TreePool::sharedPool()->createTreeNode<IntegerNode>(size)) {
|
||||
if (numberOfDigits == 1 && digits[0] == 0) {
|
||||
negative = false;
|
||||
}
|
||||
node()->setDigits(digits, numberOfDigits, negative);
|
||||
}
|
||||
|
||||
Integer::Integer(const native_uint_t * digits, size_t numberOfDigits, bool negative) :
|
||||
Integer(numberOfDigits*sizeof(native_uint_t)+sizeof(IntegerNode), digits, numberOfDigits, negative)
|
||||
{}
|
||||
|
||||
Integer::Integer(const char * digits, size_t length, bool negative) :
|
||||
Number(nullptr)
|
||||
{
|
||||
@@ -494,29 +467,39 @@ Integer::Integer(const char * digits, size_t length, bool negative) :
|
||||
}
|
||||
|
||||
Integer::Integer(const NaturalIntegerAbstract * naturalInteger) :
|
||||
Integer(naturalInteger->numberOfDigits()*sizeof(native_uint_t)+sizeof(IntegerNode))
|
||||
Integer(naturalInteger->digits(), naturalInteger->numberOfDigits(), false)
|
||||
{
|
||||
node()->setDigits(naturalInteger->digits(), naturalInteger->numberOfDigits(), false);
|
||||
}
|
||||
|
||||
Integer::Integer(native_int_t i) :
|
||||
Integer(i == 0 ? sizeof(IntegerNode) : sizeof(IntegerNode)+sizeof(native_uint_t))
|
||||
Number(nullptr)
|
||||
{
|
||||
node()->setDigits(i);
|
||||
if (i == 0) {
|
||||
*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);
|
||||
}
|
||||
|
||||
Integer::Integer(double_native_int_t i) :
|
||||
Number(nullptr)
|
||||
{
|
||||
double_native_uint_t j = i;
|
||||
if (i == 0) {
|
||||
*this = Integer(sizeof(IntegerNode));
|
||||
} else if (j <= 0xFFFFFFFF) {
|
||||
*this = Integer(sizeof(IntegerNode)+sizeof(native_uint_t));
|
||||
} else {
|
||||
*this = Integer(sizeof(IntegerNode)+2*sizeof(native_uint_t));
|
||||
*this = Integer((const native_uint_t *)nullptr, 0, false);
|
||||
return;
|
||||
}
|
||||
node()->setDigits(i);
|
||||
double_native_uint_t j = i < 0 ? -i : i;
|
||||
native_uint_t * digits = (native_uint_t *)&j;
|
||||
native_uint_t leastSignificantDigit = *digits;
|
||||
native_uint_t mostSignificantDigit = *(digits+1);
|
||||
native_uint_t digitsArray[2] = {leastSignificantDigit, mostSignificantDigit};
|
||||
if (mostSignificantDigit == 0) {
|
||||
*this = Integer(digitsArray, 1, i < 0);
|
||||
return;
|
||||
}
|
||||
*this = Integer(digitsArray, 2, i < 0);
|
||||
}
|
||||
|
||||
int Integer::extractedInt() const {
|
||||
|
||||
Reference in New Issue
Block a user