mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-20 06:10:31 +01:00
[poincare] Use small variable types in Nodes
This commit is contained in:
@@ -23,7 +23,7 @@ public:
|
||||
m_exponent(0),
|
||||
m_numberOfDigitsInMantissa(0) {}
|
||||
|
||||
virtual void setValue(const native_uint_t * mantissaDigits, size_t mantissaSize, int exponent, bool negative);
|
||||
virtual void setValue(const native_uint_t * mantissaDigits, uint8_t mantissaSize, int exponent, bool negative);
|
||||
|
||||
Integer signedMantissa() const;
|
||||
Integer unsignedMantissa() const;
|
||||
@@ -77,7 +77,7 @@ private:
|
||||
void setNegative(bool negative) { m_negative = negative; }
|
||||
bool m_negative;
|
||||
int m_exponent;
|
||||
size_t m_numberOfDigitsInMantissa;
|
||||
uint8_t m_numberOfDigitsInMantissa;
|
||||
native_uint_t m_mantissa[0];
|
||||
};
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ private:
|
||||
void didRemoveChildAtIndex(int index, LayoutCursor * cursor, bool force) override;
|
||||
bool willReplaceChild(LayoutNode * oldChild, LayoutNode * newChild, LayoutCursor * cursor, bool force) override;
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override {}
|
||||
int m_numberOfChildren;
|
||||
// See comment on NAryExpressionNode
|
||||
uint16_t m_numberOfChildren;
|
||||
};
|
||||
|
||||
class HorizontalLayoutRef : public LayoutReference {
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
Integer(native_int_t i = 0);
|
||||
Integer(double_native_int_t i);
|
||||
Integer(native_uint_t * digits, uint16_t numberOfDigits, bool negative, bool enableOverflow = false);
|
||||
Integer(const char * digits, size_t length, bool negative);
|
||||
Integer(const char * digits, uint8_t length, bool negative);
|
||||
Integer(const char * digits) : Integer(digits, strlen(digits), false) {}
|
||||
static Integer Overflow(bool negative) { return Integer((native_uint_t *)nullptr, k_maxNumberOfDigits+1, negative); }
|
||||
~Integer();
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
|
||||
// Getters
|
||||
const native_uint_t * digits() const { return usesImmediateDigit() ? &m_digit : m_digits; }
|
||||
size_t numberOfDigits() const { return m_numberOfDigits; }
|
||||
uint8_t numberOfDigits() const { return m_numberOfDigits; }
|
||||
|
||||
// Serialization
|
||||
int serialize(char * buffer, int bufferSize) const;
|
||||
@@ -143,7 +143,7 @@ private:
|
||||
}
|
||||
|
||||
bool usesImmediateDigit() const { return m_numberOfDigits == 1; }
|
||||
native_uint_t digit(size_t i) const {
|
||||
native_uint_t digit(uint8_t i) const {
|
||||
assert(i >= 0 && i < m_numberOfDigits);
|
||||
return (usesImmediateDigit() ? m_digit : m_digits[i]);
|
||||
}
|
||||
@@ -154,7 +154,7 @@ private:
|
||||
bool isOverflow() const { return m_numberOfDigits == k_maxNumberOfDigits + 1 && m_digits == nullptr; }
|
||||
|
||||
bool m_negative;
|
||||
size_t m_numberOfDigits; // In base native_uint_t
|
||||
uint8_t m_numberOfDigits; // In base native_uint_t
|
||||
union {
|
||||
native_uint_t * m_digits; // Little-endian
|
||||
native_uint_t m_digit;
|
||||
|
||||
@@ -51,8 +51,11 @@ public:
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
|
||||
private:
|
||||
template<typename T> Evaluation<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
/* We could store 2 uint8_t but multiplying m_numberOfRows and
|
||||
* m_numberOfColumns could then lead to overflow. As we are unlikely to use
|
||||
* greater matrix than 100*100, uint16_t is fine. */
|
||||
uint16_t m_numberOfRows;
|
||||
uint16_t m_numberOfColumns;
|
||||
};
|
||||
|
||||
class Matrix : public Expression {
|
||||
|
||||
@@ -47,8 +47,9 @@ public:
|
||||
MatrixComplex<T> inverse() const;
|
||||
MatrixComplex<T> transpose() const;
|
||||
private:
|
||||
int m_numberOfRows;
|
||||
int m_numberOfColumns;
|
||||
// See comment on Matrix
|
||||
uint16_t m_numberOfRows;
|
||||
uint16_t m_numberOfColumns;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -26,7 +26,9 @@ public:
|
||||
Expression squashUnaryHierarchyInPlace();
|
||||
|
||||
protected:
|
||||
int m_numberOfChildren;
|
||||
/* With a pool of size < 120k and TreeNode of size 20, a node can't have more
|
||||
* than 6144 children which fit in uint16_t. */
|
||||
uint16_t m_numberOfChildren;
|
||||
private:
|
||||
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
int simplificationOrderGreaterType(const ExpressionNode * e, bool canBeInterrupted) const override;
|
||||
|
||||
@@ -13,7 +13,7 @@ public:
|
||||
m_negative(false),
|
||||
m_numberOfDigitsNumerator(0),
|
||||
m_numberOfDigitsDenominator(0) {}
|
||||
virtual void setDigits(const native_uint_t * i, size_t numeratorSize, const native_uint_t * j, size_t denominatorSize, bool negative);
|
||||
virtual void setDigits(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative);
|
||||
|
||||
Integer signedNumerator() const;
|
||||
Integer unsignedNumerator() const;
|
||||
@@ -61,8 +61,8 @@ private:
|
||||
Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override;
|
||||
Expression denominator(Context & context, Preferences::AngleUnit angleUnit) const override;
|
||||
bool m_negative;
|
||||
size_t m_numberOfDigitsNumerator;
|
||||
size_t m_numberOfDigitsDenominator;
|
||||
uint8_t m_numberOfDigitsNumerator;
|
||||
uint8_t m_numberOfDigitsDenominator;
|
||||
native_uint_t m_digits[0];
|
||||
};
|
||||
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
|
||||
private:
|
||||
Rational(const native_uint_t * i, size_t numeratorSize, const native_uint_t * j, size_t denominatorSize, bool negative);
|
||||
Rational(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative);
|
||||
RationalNode * node() { return static_cast<RationalNode *>(Number::node()); }
|
||||
|
||||
/* Simplification */
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <strings.h>
|
||||
#include <stdint.h>
|
||||
#if POINCARE_TREE_LOG
|
||||
#include <ostream>
|
||||
#endif
|
||||
@@ -143,9 +144,9 @@ private:
|
||||
changeParentIdentifierInChildren(m_identifier);
|
||||
}
|
||||
void changeParentIdentifierInChildren(int id) const;
|
||||
int m_identifier;
|
||||
int m_parentIdentifier;
|
||||
int m_referenceCounter;
|
||||
int16_t m_identifier;
|
||||
int16_t m_parentIdentifier;
|
||||
int8_t m_referenceCounter;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ void removeZeroAtTheEnd(Integer * i) {
|
||||
assert(!i->isInfinity());
|
||||
}
|
||||
|
||||
void DecimalNode::setValue(const native_uint_t * mantissaDigits, size_t mantissaSize, int exponent, bool negative) {
|
||||
void DecimalNode::setValue(const native_uint_t * mantissaDigits, uint8_t mantissaSize, int exponent, bool negative) {
|
||||
m_negative = negative;
|
||||
m_exponent = exponent;
|
||||
m_numberOfDigitsInMantissa = mantissaSize;
|
||||
|
||||
@@ -130,7 +130,7 @@ Integer::Integer(double_native_int_t i) {
|
||||
m_negative = i < 0;
|
||||
}
|
||||
|
||||
Integer::Integer(const char * digits, size_t length, bool negative) :
|
||||
Integer::Integer(const char * digits, uint8_t length, bool negative) :
|
||||
Integer(0)
|
||||
{
|
||||
if (digits != nullptr && digits[0] == '-') {
|
||||
@@ -140,7 +140,7 @@ Integer::Integer(const char * digits, size_t length, bool negative) :
|
||||
}
|
||||
if (digits != nullptr) {
|
||||
Integer base(10);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
for (uint8_t i = 0; i < length; i++) {
|
||||
*this = Multiplication(*this, base);
|
||||
*this = Addition(*this, Integer(*digits-'0'));
|
||||
digits++;
|
||||
@@ -182,7 +182,7 @@ Integer::Integer(const Integer& other) {
|
||||
m_digit = other.m_digit;
|
||||
} else {
|
||||
native_uint_t * digits = allocDigits(other.m_numberOfDigits);
|
||||
for (size_t i = 0; i < other.m_numberOfDigits; i++) {
|
||||
for (uint8_t i = 0; i < other.m_numberOfDigits; i++) {
|
||||
digits[i] = other.m_digits[i];
|
||||
}
|
||||
m_digits = digits;
|
||||
@@ -219,7 +219,7 @@ Integer& Integer::operator=(const Integer& other) {
|
||||
m_digit = other.m_digit;
|
||||
} else {
|
||||
native_uint_t * digits = allocDigits(other.m_numberOfDigits);
|
||||
for (size_t i = 0; i < other.m_numberOfDigits; i++) {
|
||||
for (uint8_t i = 0; i < other.m_numberOfDigits; i++) {
|
||||
digits[i] = other.m_digits[i];
|
||||
}
|
||||
m_digits = digits;
|
||||
@@ -326,7 +326,7 @@ T Integer::approximate() const {
|
||||
* the resulting uint64_t (as required by IEEE754). */
|
||||
assert(IEEE754<T>::size()-numberOfBitsInLastDigit >= 0 && IEEE754<T>::size()-numberOfBitsInLastDigit < 64); // Shift operator behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand
|
||||
mantissa |= ((uint64_t)lastDigit << (IEEE754<T>::size()-numberOfBitsInLastDigit));
|
||||
size_t digitIndex = 2;
|
||||
uint8_t digitIndex = 2;
|
||||
int numberOfBits = numberOfBitsInLastDigit;
|
||||
/* Complete the mantissa by inserting, from left to right, every digit of the
|
||||
* Integer from the most significant one to the last from. We break when
|
||||
@@ -448,23 +448,23 @@ Integer Integer::multiplication(const Integer & a, const Integer & b, bool oneDi
|
||||
return Integer::Overflow(a.m_negative != b.m_negative);
|
||||
}
|
||||
|
||||
size_t size = min(a.m_numberOfDigits + b.m_numberOfDigits, k_maxNumberOfDigits + oneDigitOverflow); // Enable overflowing of 1 digit
|
||||
uint8_t size = min(a.m_numberOfDigits + b.m_numberOfDigits, k_maxNumberOfDigits + oneDigitOverflow); // Enable overflowing of 1 digit
|
||||
|
||||
native_uint_t * digits = allocDigits(size);
|
||||
memset(digits, 0, size*sizeof(native_uint_t));
|
||||
|
||||
double_native_uint_t carry = 0;
|
||||
for (size_t i = 0; i < a.m_numberOfDigits; i++) {
|
||||
for (uint8_t i = 0; i < a.m_numberOfDigits; i++) {
|
||||
double_native_uint_t aDigit = a.digit(i);
|
||||
carry = 0;
|
||||
for (size_t j = 0; j < b.m_numberOfDigits; j++) {
|
||||
for (uint8_t j = 0; j < b.m_numberOfDigits; j++) {
|
||||
double_native_uint_t bDigit = b.digit(j);
|
||||
/* The fact that aDigit and bDigit are double_native is very important,
|
||||
* otherwise the product might end up being computed on single_native size
|
||||
* and then zero-padded. */
|
||||
double_native_uint_t p = aDigit*bDigit + carry + (double_native_uint_t)(digits[i+j]); // TODO: Prove it cannot overflow double_native type
|
||||
native_uint_t * l = (native_uint_t *)&p;
|
||||
if (i+j < (size_t) k_maxNumberOfDigits+oneDigitOverflow) {
|
||||
if (i+j < (uint8_t) k_maxNumberOfDigits+oneDigitOverflow) {
|
||||
digits[i+j] = l[0];
|
||||
} else {
|
||||
if (l[0] != 0) {
|
||||
@@ -474,7 +474,7 @@ Integer Integer::multiplication(const Integer & a, const Integer & b, bool oneDi
|
||||
} }
|
||||
carry = l[1];
|
||||
}
|
||||
if (i+b.m_numberOfDigits < (size_t) k_maxNumberOfDigits+oneDigitOverflow) {
|
||||
if (i+b.m_numberOfDigits < (uint8_t) k_maxNumberOfDigits+oneDigitOverflow) {
|
||||
digits[i+b.m_numberOfDigits] += carry;
|
||||
} else {
|
||||
if (carry != 0) {
|
||||
@@ -514,18 +514,18 @@ Integer Integer::usum(const Integer & a, const Integer & b, bool subtract, bool
|
||||
return Integer::Overflow(a.m_negative != b.m_negative);
|
||||
}
|
||||
|
||||
size_t size = max(a.m_numberOfDigits, b.m_numberOfDigits);
|
||||
uint8_t size = max(a.m_numberOfDigits, b.m_numberOfDigits);
|
||||
if (!subtract) {
|
||||
// Addition can overflow
|
||||
size++;
|
||||
}
|
||||
native_uint_t * digits = allocDigits(max(size, k_maxNumberOfDigits+oneDigitOverflow));
|
||||
bool carry = false;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
for (uint8_t i = 0; i < size; i++) {
|
||||
native_uint_t aDigit = (i >= a.m_numberOfDigits ? 0 : a.digit(i));
|
||||
native_uint_t bDigit = (i >= b.m_numberOfDigits ? 0 : b.digit(i));
|
||||
native_uint_t result = (subtract ? aDigit - bDigit - carry : aDigit + bDigit + carry);
|
||||
if (i < (size_t) (k_maxNumberOfDigits + oneDigitOverflow)) {
|
||||
if (i < (uint8_t) (k_maxNumberOfDigits + oneDigitOverflow)) {
|
||||
digits[i] = result;
|
||||
} else {
|
||||
if (result != 0) {
|
||||
@@ -551,7 +551,7 @@ Integer Integer::multiplyByPowerOf2(uint8_t pow) const {
|
||||
assert(pow < 32);
|
||||
native_uint_t * digits = allocDigits(m_numberOfDigits+1);
|
||||
native_uint_t carry = 0;
|
||||
for (size_t i = 0; i < m_numberOfDigits; i++) {
|
||||
for (uint8_t i = 0; i < m_numberOfDigits; i++) {
|
||||
digits[i] = digit(i) << pow | carry;
|
||||
carry = pow == 0 ? 0 : digit(i) >> (32-pow);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Poincare {
|
||||
|
||||
/* Rational Node */
|
||||
|
||||
void RationalNode::setDigits(const native_uint_t * numeratorDigits, size_t numeratorSize, const native_uint_t * denominatorDigits, size_t denominatorSize, bool negative) {
|
||||
void RationalNode::setDigits(const native_uint_t * numeratorDigits, uint8_t numeratorSize, const native_uint_t * denominatorDigits, uint8_t denominatorSize, bool negative) {
|
||||
m_negative = negative;
|
||||
m_numberOfDigitsNumerator = numeratorSize;
|
||||
m_numberOfDigitsDenominator = denominatorSize;
|
||||
@@ -41,9 +41,9 @@ Integer RationalNode::denominator() const {
|
||||
|
||||
// Tree Node
|
||||
|
||||
static inline size_t RationalSize(size_t numeratorNumberOfDigits, size_t denominatorNumberOfDigits) {
|
||||
size_t realNumeratorSize = numeratorNumberOfDigits > Integer::k_maxNumberOfDigits ? 0 : numeratorNumberOfDigits;
|
||||
size_t realDenominatorSize = denominatorNumberOfDigits > Integer::k_maxNumberOfDigits ? 0 : denominatorNumberOfDigits;
|
||||
static inline size_t RationalSize(uint8_t numeratorNumberOfDigits, uint8_t denominatorNumberOfDigits) {
|
||||
uint8_t realNumeratorSize = numeratorNumberOfDigits > Integer::k_maxNumberOfDigits ? 0 : numeratorNumberOfDigits;
|
||||
uint8_t realDenominatorSize = denominatorNumberOfDigits > Integer::k_maxNumberOfDigits ? 0 : denominatorNumberOfDigits;
|
||||
return sizeof(RationalNode) + sizeof(native_uint_t)*(realNumeratorSize + realDenominatorSize);
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ Rational Rational::IntegerPower(const Rational & i, const Integer & j) {
|
||||
return Rational(newNumerator, newDenominator);
|
||||
}
|
||||
|
||||
Rational::Rational(const native_uint_t * i, size_t numeratorSize, const native_uint_t * j, size_t denominatorSize, bool negative) :
|
||||
Rational::Rational(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative) :
|
||||
Number(TreePool::sharedPool()->createTreeNode<RationalNode>(RationalSize(numeratorSize, denominatorSize)))
|
||||
{
|
||||
static_cast<RationalNode *>(node())->setDigits(i, numeratorSize, j, denominatorSize, negative);
|
||||
|
||||
Reference in New Issue
Block a user