#include #include #include #include #include #include #define MAX(a,b) ((a)>(b)?a:b) #define NATIVE_UINT_BIT_COUNT (8*sizeof(native_uint_t)) #define INTEGER_IMMEDIATE_LIMIT 32 uint8_t log2(native_uint_t v) { assert(NATIVE_UINT_BIT_COUNT < 256); // Otherwise uint8_t isn't OK for (uint8_t i=0; i= m_numberOfDigits ? 0 : m_digits[i]); native_uint_t b = (i >= other.m_numberOfDigits ? 0 : other.m_digits[i]); native_uint_t sum = a + b + carry; // TODO: Prove it cannot overflow digits[i] = sum; carry = ((a>sum)||(b>sum)); } while (digits[sumSize-1] == 0) { sumSize--; /* At this point we may realloc m_digits 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(digits, sumSize); } const Integer Integer::operator*(const Integer &other) const { uint16_t productSize = other.m_numberOfDigits + m_numberOfDigits; native_uint_t * bits = (native_uint_t *)malloc(productSize*sizeof(native_uint_t)); memset(bits, 0, productSize*sizeof(native_uint_t)); native_uint_t carry = 0; for (uint16_t i=0; i>32; //FIXME: 32 is hardcoded here! } m_digits[i+other.m_numberOfDigits] = carry; } return Integer(bits, 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(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(e); return (i != NULL); */ return false; } Expression ** Integer::children() { return NULL; } void Integer::layout() { //m_frame.size = KDStringSize(m_stringValue); } void Integer::draw() { // KDDrawString(m_stringValue, KDPOINT(0,0)); } float Integer::approximate() { union { uint32_t uint_result; float float_result; }; assert(sizeof(float) == 4); /* We're generating an IEEE 754 compliant float. * Theses numbers are 32-bit values, stored as follow: * sign (1 bit) * exponent (8 bits) * mantissa (23 bits) * * We can tell that: * - the sign is going to be 0 for now, we only handle positive numbers * - the exponent is the length of our BigInt, in bits + 127 * - the mantissa is the beginning of our BigInt */ //bool sign = 0; native_uint_t lastDigit = m_digits[m_numberOfDigits-1]; uint8_t numberOfBitsInLastDigit = log2(lastDigit); uint8_t exponent = 127; exponent += (m_numberOfDigits-1)*32; exponent += numberOfBitsInLastDigit; uint32_t mantissa = 0; mantissa |= (lastDigit << (32-numberOfBitsInLastDigit)); if (m_numberOfDigits >= 2) { native_uint_t beforeLastDigit = m_digits[m_numberOfDigits-2]; mantissa |= (beforeLastDigit >> numberOfBitsInLastDigit); } uint_result = 0; //uint_result |= (sign << 31); uint_result |= (exponent << 23); uint_result |= (mantissa >> (32-23) & 0x7FFFFF); return float_result; }