//divides the number by 10 in its native base by literally shifting digit void bignum::rightShift(int places) { for (int i = places; i > 0; i--) { for (int n = right_most; n <= digitCount; n++) { if (n == 0) continue; digits[n - 1] = digits[n]; } updateDigits(); } updateDigits(); }
void bignum::roundUpToIndex(int index) { //first checks to see if the number is already rounded bignum round_test; round_test.setBase(base); round_test.setDigit(index, 1); //checks to see if number is already rounded without using modulo to prevent stack overflow for (int i = 0; i < index; i++) { if (digits[i] != 0) break; else if (i == index - 1) return; } for (int i = 0; i < index; i++) setDigit(i, 0); if (isPositive()) { bignum increment; increment.setDigit(index, 1); increment.setBase(base); *this += increment; } updateDigits(); }
//rounds the number to a specific position of digits[index] void bignum::roundToIndex(int index) { if (index == 0) return; if (index > MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The target index is higher than the maximum digit count"); if (index < 1) return; //checks to see if number is already rounded without using modulo to prevent stack overflow for (int i = 0; i < index; i++) { if (digits[i] != 0) break; else if (i == index - 1) return; } if (digits[index - 1] >= (base / 2)) { bignum increment; increment.setBase(base); increment.setDigit(index, 1); isNegative() ? *this -= increment : *this += increment; } for (int i = 0; i < index; i++) digits[i] = 0; updateDigits(); }
//rounds the number to a speecific position, rounding each previous digit first void bignum::roundAllDigitsToIndex(int index) { if (index == 0) return; if (index > MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The target index is higher than the maximum digit count"); if (index < 1) return; for (int i = 1; i <= index; i++) { if (digits[i - 1] >= (base / 2)) { bignum increment; increment.setBase(base); increment.setDigit(i, 1); isNegative() ? *this -= increment : *this += increment; } } for (int i = 0; i < index; i++) digits[i] = 0; updateDigits(); }
void bignum::convertBaseSimple(int n) { if (base != n) { bool original_negative = negative; bignum zero; zero.setBase(base); bignum counter(absolute()); bignum converted; converted.setBase(n); while (counter > zero) { converted++; counter--; } *this = converted; negative = original_negative; } updateDigits(); }
bignum& bignum::operator = (const bignum& bn) { if (this == &bn) return *this; base = bn.getBase(); int highestDigits = 0; int decimal = 0; highestDigits = (digitCount < bn.getDigitCount() ? bn.getDigitCount() : digitCount); decimal = (decimalCount < bn.getDecimalCount() ? bn.getDecimalCount() : decimalCount); for (int i = (ONES_PLACE - decimal); i < highestDigits; i++) { if (i >= MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided"); digits[i] = bn.getDigit(i); } negative = bn.isNegative(); updateDigits(); return *this; }
void bignum::initializeBignum() { for (int i = 0; i < MAXDIGITS; i++) digits[i] = 0; base = 10; updateDigits(); }
//multiplies the number by 10 in its native base by literally shifting digit void bignum::leftShift(int places) { for (int i = 0; i < places; i++) { for (int c = 0; c < digitRange; c++) { if (digitCount - c >= MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided"); digits[digitCount - c] = digits[left_most - c]; } digits[right_most] = 0; updateDigits(); } updateDigits(); }
//----------------------------------------------------------------------------- // main void main(void) { initPorts(); initTimer1(); initUART(); while(1) { updateDigits(); updateDisplay(); if(beepCounter<115) beepCounter++; // beeper off count else { beepCounter = 0; BEEP_BEEP_OFF; } if(secondCounter<1000) secondCounter++; // 1 second tasks else { if(LATBbits.LATB0 == 0) COLON_ON; // blink colon once per second else COLON_OFF; secondCounter = 0; } if(lnetTimeoutCounter<14580) lnetTimeoutCounter++; // (lnet timeout 14.58 sec) else // no overlap with 1 sec { LNET_OFF; lnetConnected = FALSE; PM_OFF; lnetHours = 88; lnetMinutes = 88; } // tasks that execute once per second are located in secTasks() while(TMR1H < 0x09); while(TMR1L < 0xC4); // wait for 1 ms to elapse TMR1H = 0; TMR1L = 0; // reset tmr1 registers } return; }
bignum::bignum(vector<int> n, int set_base, bool is_negative) { initializeBignum(); base = set_base; int count = (ONES_PLACE - 1) + n.size(); for (vector<int>::iterator i = n.begin(); i != n.end() && count >= 0; i++) { if (count >= MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided"); if (*i >= base) throw error_handler(__FILE__, __LINE__, "One of the values passed is beyond the given base"); digits[count] = (*i); count--; } updateDigits(); negative = is_negative; }
bignum::bignum(string s, int baseGiven) { initializeBignum(); base = baseGiven; vector <int> numbersToAdd; int numbersAdded = 0; int decimalNumbers = 0; for (int i = 0; i < s.length(); i++) { bool decimal = false; switch (s[i]) { case ',': break; case '.': if (decimal == true) throw error_handler(__FILE__, __LINE__, "constructor failed, number contains multiple decimal points"); else decimal = true; break; case '-': if (negative == true) throw error_handler(__FILE__, __LINE__, "constructor failed, number contains multiple negative symbols"); else negative = true; break; default: char zero = '0'; char letter = 'A'; if (s[i] >= zero && s[i] <= zero + 9) { int digitToAdd = s[i] - zero; if (digitToAdd >= base) throw error_handler(__FILE__, __LINE__, "constructor failed, digit exceeds base desired"); if (decimal == true) decimalNumbers++; numbersAdded++; numbersToAdd.push_back(digitToAdd); break; } else if (s[i] >= letter && s[i] <= letter + 27) { int digitToAdd = s[i] - letter + 10; if (digitToAdd >= base) throw error_handler(__FILE__, __LINE__, "constructor failed, digit exceeds base desired"); if (decimal == true) decimalNumbers++; numbersAdded++; numbersToAdd.push_back(digitToAdd); break; } else throw error_handler(__FILE__, __LINE__, "constructor failed, invalid character(s) included"); break; } } if (decimalNumbers > ONES_PLACE) throw error_handler(__FILE__, __LINE__, "constructor failed, number has too many decimal places"); int startingPoint = ONES_PLACE + (numbersAdded - decimalNumbers) - 1; for (int i = 0; i < numbersToAdd.size(); i++) { int digitToAdd = numbersToAdd.at(i); int locationToSet = startingPoint - i; digits[locationToSet] = digitToAdd; } updateDigits(); }
bignum::bignum(string s) { initializeBignum(); vector <int> numbersToAdd; int numbersAdded = 0; int decimalNumbers = 0; bool decimal = false; int commaNumbers = 0; bool comma = false; for (int i = 0; i < s.length(); i++) { switch (s[i]) { case ',': if (decimal == true) throw error_handler(__FILE__, __LINE__, "constructor failed, comma included after decimal point"); else if (comma == true && commaNumbers != 3) throw error_handler(__FILE__, __LINE__, "constructor failed, improper use of commas"); else if (comma == false && numbersAdded > 3) throw error_handler(__FILE__, __LINE__, "constructor failed, improper use of commas"); else if (numbersAdded == 0) throw error_handler(__FILE__, __LINE__, "constructor failed, improper use of commas"); comma = true; commaNumbers = 0; break; case '.': if (decimal == true) throw error_handler(__FILE__, __LINE__, "constructor failed, number contains multiple decimal points"); else decimal = true; break; case '-': if (decimal == true) throw error_handler(__FILE__, __LINE__, "constructor failed, negative symbol included after a decimal point"); if (numbersAdded > 0) throw error_handler(__FILE__, __LINE__, "constructor failed, negative symbol included after a number"); if (comma == true) throw error_handler(__FILE__, __LINE__, "constructor failed, negative sign included after a comma"); if (negative == true) throw error_handler(__FILE__, __LINE__, "constructor failed, number contains multiple negative symbols"); else negative = true; break; default: char zero = '0'; if (s[i] >= zero && s[i] <= zero + 9) { int digitToAdd = s[i] - zero; if (digitToAdd >= base) throw error_handler(__FILE__, __LINE__, "constructor failed, digit exceeds base desired"); if (decimal == true) decimalNumbers++; if (comma == true) commaNumbers++; numbersAdded++; numbersToAdd.push_back(digitToAdd); break; } else throw error_handler(__FILE__, __LINE__, "constructor failed, invalid character(s) included"); break; } } if (decimalNumbers > ONES_PLACE) throw error_handler(__FILE__, __LINE__, "constructor failed, number has too many decimal places"); int startingPoint = ONES_PLACE + (numbersAdded - decimalNumbers) - 1; for (int i = 0; i < numbersToAdd.size(); i++) { int digitToAdd = numbersToAdd.at(i); int locationToSet = startingPoint - i; digits[locationToSet] = digitToAdd; } updateDigits(); }
void bignum::convertBase(int n) { if (isZero()) { base = n; return; } bool original_negative = negative; bignum toAdd; bignum temp(0); temp.setBase(n); bignum original_ten(10); original_ten.setBase(base); bignum converted_ten(original_ten); converted_ten.convertBaseSimple(n); bignum original_nth; bignum converted_nth; if (base != n) { for (int i = 0; i < digitRange; i++) { int index(left_most - i); if (i == 0) { original_nth = bignum(index - ONES_PLACE); original_nth.convertBaseSimple(base); converted_nth = bignum(original_nth); converted_nth.convertBaseSimple(n); } else converted_nth--; if (index >= MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided"); if (index < 0) break; //each digit of the number is evaluated evaluated X * 10^n format bignum original_digit(getDigit(index)); if (original_digit.isZero()) continue; original_digit.convertBaseSimple(base); //each of the above format is converted simply bignum converted_digit(original_digit); converted_digit.convertBaseSimple(n); //add X * 10^n to the solution bignum multiplier(exponent(converted_ten, converted_nth)); bignum toAdd = converted_digit * multiplier; temp += toAdd; } *this = temp; } negative = original_negative; updateDigits(); }