mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[Poincare] First working BigInt addition!
This commit is contained in:
@@ -4,20 +4,34 @@
|
||||
#include <poincare/expression.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t native_uint_t;
|
||||
|
||||
class Integer : public Expression {
|
||||
public:
|
||||
Integer(native_uint_t i);
|
||||
Integer(char * string);
|
||||
Integer(uint32_t integer);
|
||||
~Integer();
|
||||
//Number(int v);
|
||||
|
||||
virtual void draw();
|
||||
virtual Expression ** children();
|
||||
virtual bool identicalTo(Expression * e);
|
||||
//Integer add(Integer * i);
|
||||
const Integer operator+(const Integer &other) const;
|
||||
bool operator==(const Integer &other) const;
|
||||
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 * bits, uint16_t length);
|
||||
uint16_t m_numberOfBits;
|
||||
void * m_bits;
|
||||
native_uint_t * m_bits;
|
||||
/*
|
||||
// TODO: Small-int optimization
|
||||
union {
|
||||
uint32_t m_staticBits;
|
||||
char * m_dynamicBits;
|
||||
};
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,21 +3,72 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Integer::Integer(uint32_t integer) {
|
||||
// FIXME: Suboptimal (and somewhat wrong, too!)
|
||||
m_numberOfBits = 32;
|
||||
m_bits = malloc(4);
|
||||
*(uint32_t *)m_bits = integer;
|
||||
#define MAX(a,b) ((a)>(b)?a:b)
|
||||
|
||||
#define INTEGER_IMMEDIATE_LIMIT 32
|
||||
|
||||
uint16_t Integer::arraySize(uint16_t bitSize) {
|
||||
return (bitSize-1)/(8*sizeof(native_uint_t))+1;
|
||||
}
|
||||
|
||||
bool Integer::identicalTo(Expression * e) {
|
||||
/* FIXME
|
||||
Integer * i = dynamic_cast<Integer *>(e);
|
||||
return (i != NULL);
|
||||
*/
|
||||
bool Integer::operator==(const Integer &other) const {
|
||||
if (other.m_numberOfBits != m_numberOfBits) {
|
||||
return false;
|
||||
}
|
||||
uint16_t size = arraySize(m_numberOfBits);
|
||||
for (uint16_t i=0; i<size; i++) {
|
||||
if (m_bits[i] != other.m_bits[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Integer::Integer(native_uint_t i) {
|
||||
//m_numberOfBits = sizeof(native_uint_t)*8;
|
||||
m_numberOfBits = 16;
|
||||
m_bits = (native_uint_t *)malloc(sizeof(native_uint_t));
|
||||
*m_bits = i;
|
||||
}
|
||||
|
||||
const Integer Integer::operator+(const Integer &other) const {
|
||||
uint16_t sumSize = MAX(other.m_numberOfBits,m_numberOfBits) + 1;
|
||||
uint16_t intArraySize = arraySize(sumSize);
|
||||
native_uint_t * bits = (native_uint_t *)malloc(intArraySize*sizeof(native_uint_t));
|
||||
bool carry = 0;
|
||||
for (uint16_t i = 0; i<intArraySize; i++) {
|
||||
native_uint_t a = other.m_bits[i];
|
||||
native_uint_t b = m_bits[i];
|
||||
native_uint_t sum = a + b + carry;
|
||||
bits[i] = sum;
|
||||
carry = ((a>sum)||(b>sum));
|
||||
}
|
||||
if (carry) {
|
||||
bits[intArraySize] = 0x1;
|
||||
} else {
|
||||
sumSize -= 1;
|
||||
/* At this point we may realloc m_bits to a smaller size.
|
||||
* It might not be worth the trouble though : it won't happen very often
|
||||
* and we're wasting a single native_uint_t. */
|
||||
}
|
||||
return Integer(bits, sumSize);
|
||||
}
|
||||
|
||||
/*
|
||||
char * Integer::bits() {
|
||||
if (m_numberOfBits > INTEGER_IMMEDIATE_LIMIT) {
|
||||
return m_dynamicBits;
|
||||
} else {
|
||||
return &m_staticBits;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Integer::Integer(native_uint_t * bits, uint16_t size) :
|
||||
m_bits(bits),
|
||||
m_numberOfBits(size) {
|
||||
}
|
||||
|
||||
Integer::Integer(char * string) {
|
||||
int base = 10;
|
||||
int stringLength = strlen(string);
|
||||
@@ -47,32 +98,17 @@ Integer::Integer(char * string) {
|
||||
//int num_bytes = ceilf(log2*stringLength)/8;
|
||||
// FIXME: We don't have ceilf just yet. Do we really need it though?
|
||||
m_numberOfBits = (log2*stringLength);
|
||||
m_bits = malloc(m_numberOfBits/8+1);
|
||||
|
||||
|
||||
|
||||
m_bits = (native_uint_t *)malloc(arraySize(m_numberOfBits)*sizeof(native_uint_t));
|
||||
}
|
||||
|
||||
Integer::~Integer() {
|
||||
free(m_bits);
|
||||
bool Integer::identicalTo(Expression * e) {
|
||||
/* FIXME
|
||||
Integer * i = dynamic_cast<Integer *>(e);
|
||||
return (i != NULL);
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Number::Number(int v) : m_value(v) {
|
||||
for (int i=0; i<16; i++) {
|
||||
m_stringValue[i] = 0;
|
||||
}
|
||||
|
||||
int value = v;
|
||||
for (int i=0; i<15; i++) {
|
||||
int digit = value - 10*(value/10);
|
||||
m_stringValue[i] = '0' + digit;
|
||||
value = value/10;
|
||||
if (value == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
Expression ** Integer::children() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#include <quiz.h>
|
||||
#include <poincare.h>
|
||||
#include <assert.h>
|
||||
|
||||
QUIZ_CASE(poincare_integer) {
|
||||
Integer i = Integer((char *)"123");
|
||||
assert(Integer(123) == Integer(123));
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_integer_add) {
|
||||
assert(Integer(123)+Integer(456) == Integer(579));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user