mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] refactor Integer
This commit is contained in:
@@ -10,23 +10,25 @@ typedef uint64_t double_native_uint_t;
|
||||
class Integer : public Expression {
|
||||
public:
|
||||
Integer(native_uint_t i);
|
||||
static Integer parseInteger(const char * string);
|
||||
Integer(const char * string); // NULL-terminated
|
||||
~Integer();
|
||||
|
||||
//Integer& operator=(Integer&& other); // C++11 move assignment operator
|
||||
|
||||
// Arithmetic
|
||||
const Integer operator+(const Integer &other) const;
|
||||
const Integer operator*(const Integer &other) const;
|
||||
bool operator==(const Integer &other) const;
|
||||
|
||||
virtual void draw();
|
||||
virtual Expression ** children();
|
||||
virtual bool identicalTo(Expression * e);
|
||||
//Integer add(Integer * i);
|
||||
const Integer operator+(const Integer &other) const;
|
||||
const Integer operator*(const Integer &other) const;
|
||||
bool operator==(const Integer &other) const;
|
||||
virtual float approximate();
|
||||
protected:
|
||||
virtual void layout();
|
||||
private:
|
||||
static uint16_t arraySize(uint16_t bitSize);
|
||||
/* WARNING: This constructor takes ownership of the bits array and will free it! */
|
||||
Integer(native_uint_t * digits, uint16_t numberOfDigits);
|
||||
//#error BAD DESIGN: use "number_of_digits", which is arraySize(m_numberOfBits)
|
||||
uint16_t m_numberOfDigits; // In base native_uint_max
|
||||
native_uint_t * m_digits; // LITTLE-ENDIAN
|
||||
/*
|
||||
|
||||
@@ -19,6 +19,59 @@ uint8_t log2(native_uint_t v) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
Integer::Integer(native_uint_t i) {
|
||||
m_numberOfDigits = 1;
|
||||
m_digits = (native_uint_t *)malloc(sizeof(native_uint_t));
|
||||
*m_digits = i;
|
||||
}
|
||||
|
||||
Integer::Integer(const char * string) {
|
||||
int stringLength = strlen(string);
|
||||
/*
|
||||
// Only support base 10 for now
|
||||
if (stringLength > 2 && string[0] == '0')
|
||||
switch (string[1]) {
|
||||
case 'x':
|
||||
base=16;
|
||||
break;
|
||||
case 'b':
|
||||
base = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Integer base = Integer(10);
|
||||
|
||||
Integer v = Integer(string[0]-'0');
|
||||
for (int i=1; i<stringLength; i++) {
|
||||
v = v * base;
|
||||
v = v + Integer(string[i]-'0'); // ASCII encoding
|
||||
}
|
||||
|
||||
// Pilfer v's ivars
|
||||
m_numberOfDigits = v.m_numberOfDigits;
|
||||
m_digits = v.m_digits;
|
||||
|
||||
// Zero-out v
|
||||
v.m_numberOfDigits = 0;
|
||||
v.m_digits = NULL;
|
||||
}
|
||||
|
||||
Integer::~Integer() {
|
||||
if (m_digits) {
|
||||
//free(m_digits);
|
||||
}
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
||||
Integer::Integer(native_uint_t * digits, uint16_t numberOfDigits) :
|
||||
m_numberOfDigits(numberOfDigits),
|
||||
m_digits(digits) {
|
||||
}
|
||||
|
||||
|
||||
bool Integer::operator==(const Integer &other) const {
|
||||
if (other.m_numberOfDigits != m_numberOfDigits) {
|
||||
return false;
|
||||
@@ -31,11 +84,21 @@ bool Integer::operator==(const Integer &other) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
Integer::Integer(native_uint_t i) {
|
||||
m_numberOfDigits = 1;
|
||||
m_digits = (native_uint_t *)malloc(sizeof(native_uint_t));
|
||||
*m_digits = i;
|
||||
/*
|
||||
Integer& Integer::operator=(Integer&& other) {
|
||||
if (this != &other) {
|
||||
// Release our ivars
|
||||
m_numberOfDigits = 0;
|
||||
free(m_digits);
|
||||
// Pilfer other's ivars
|
||||
m_numberOfDigits = other.m_numberOfDigits;
|
||||
m_digits = other.m_digits;
|
||||
// Reset other
|
||||
other.m_numberOfDigits = 0;
|
||||
other.m_digits = NULL;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
const Integer Integer::operator+(const Integer &other) const {
|
||||
uint16_t sumSize = MAX(other.m_numberOfDigits,m_numberOfDigits)+1;
|
||||
@@ -88,47 +151,6 @@ const Integer Integer::operator*(const Integer &other) const {
|
||||
return Integer(digits, productSize);
|
||||
}
|
||||
|
||||
/*
|
||||
char * Integer::bits() {
|
||||
if (m_numberOfDigits > INTEGER_IMMEDIATE_LIMIT) {
|
||||
return m_dynamicBits;
|
||||
} else {
|
||||
return &m_staticBits;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Integer::Integer(native_uint_t * digits, uint16_t numberOfDigits) :
|
||||
m_numberOfDigits(numberOfDigits),
|
||||
m_digits(digits) {
|
||||
}
|
||||
|
||||
Integer Integer::parseInteger(const char * string) {
|
||||
int base = 10;
|
||||
int stringLength = strlen(string);
|
||||
/*
|
||||
// Only support base 10 for now
|
||||
if (stringLength > 2 && string[0] == '0')
|
||||
switch (string[1]) {
|
||||
case 'x':
|
||||
base=16;
|
||||
break;
|
||||
case 'b':
|
||||
base = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Integer v = Integer(string[0]-'0');
|
||||
for (int i=1; i<stringLength; i++) {
|
||||
v = v * Integer(10);
|
||||
v = v + Integer(string[i]-'0'); // ASCII encoding
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
bool Integer::identicalTo(Expression * e) {
|
||||
/* FIXME
|
||||
Integer * i = dynamic_cast<Integer *>(e);
|
||||
|
||||
@@ -9,20 +9,20 @@ QUIZ_CASE(poincare_integer) {
|
||||
QUIZ_CASE(poincare_integer_add) {
|
||||
//assert(Integer((uint32_t)0) + Integer((uint32_t)0) == Integer((uint32_t)0));
|
||||
assert(Integer(123) + Integer(456) == Integer(579));
|
||||
assert(Integer::parseInteger("123456789123456789") + Integer(1) == Integer::parseInteger("123456789123456790"));
|
||||
assert(Integer("123456789123456789") + Integer(1) == Integer("123456789123456790"));
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_integer_multiply) {
|
||||
assert(Integer(12) * Integer(34) == Integer(408));
|
||||
assert(Integer(999999) * Integer(999999) == Integer::parseInteger("999998000001"));
|
||||
assert(Integer::parseInteger("9999999999") * Integer::parseInteger("9999999999") == Integer::parseInteger("99999999980000000001"));
|
||||
assert(Integer(999999) * Integer(999999) == Integer("999998000001"));
|
||||
assert(Integer("9999999999") * Integer("9999999999") == Integer("99999999980000000001"));
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_integer_parse_integer) {
|
||||
assert(Integer::parseInteger("123") == Integer(123));
|
||||
assert(Integer("123") == Integer(123));
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_integer_approximate) {
|
||||
assert(Integer(1).approximate() == 1.0f);
|
||||
assert(Integer::parseInteger("12345678").approximate() == 12345678.0f);
|
||||
assert(Integer("12345678").approximate() == 12345678.0f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user