#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 '9' ? (c-'A'+10) : (c-'0')); } Integer::Integer(Integer&& other) { // Pilfer other's data m_numberOfDigits = other.m_numberOfDigits; m_digits = other.m_digits; // Reset other other.m_numberOfDigits = 0; other.m_digits = NULL; } 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); Integer base = Integer(10); if (stringLength > 2 && string[0] == '0') { switch (string[1]) { case 'x': base = Integer(16); string += 2; stringLength -= 2; break; case 'b': base = Integer(2); string += 2; stringLength -= 2; break; } } Integer v = Integer(digit_from_char(string[0])); for (int i=1; 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); } Integer Integer::operator*(const Integer &other) const { assert(sizeof(double_native_uint_t) == 2*sizeof(native_uint_t)); uint16_t productSize = other.m_numberOfDigits + m_numberOfDigits; native_uint_t * digits = (native_uint_t *)malloc(productSize*sizeof(native_uint_t)); memset(digits, 0, productSize*sizeof(native_uint_t)); double_native_uint_t carry = 0; for (uint16_t i=0; 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)); } #endif 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 - 1 + 127; * - the mantissa is the beginning of our BigInt, discarding the first bit */ //bool sign = 0; native_uint_t lastDigit = m_digits[m_numberOfDigits-1]; uint8_t numberOfBitsInLastDigit = log2(lastDigit); uint8_t exponent = 126; 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-1) & 0x7FFFFF); return float_result; } ExpressionLayout * Integer::createLayout() { // 1 - Build string rep' // 2 - return StringLayout // FIXME return nullptr; }