void handleDigit (char *str, char ch) { const char *labelText; char buffer[BUF_SIZE]; int len; /* --- And they just did a command --- */ if (command (lastChar)) { /* --- Clear the digit field --- */ gtk_label_set_text (GTK_LABEL (label), ""); /* --- If they did a computation --- */ if (lastChar == '=') { /* --- Clear out the command --- */ lastChar = (char) 0; prevCmd = (char) 0; } } /* --- Get the buffer in the led --- */ labelText = gtk_label_get_text (GTK_LABEL (label)); strcpy (buffer, labelText); /* --- Add the new character on it. --- */ len = strlen (buffer); buffer[len] = (gchar) ch; buffer[len+1] = (gchar) 0; /* --- Trim leading zeros. --- */ trimLeadingZeros (buffer); /* --- Add digit to field. --- */ gtk_label_set_text (GTK_LABEL (label), (char *) buffer); }
BigInt& BigInt::operator %=(const BigInt& r) { if (!r.size()) throw std::invalid_argument("Divide by zero!"); /* int carry_sign = this->sign * r.sign; this->sign = POSITIVE; BigInt rr = r.abs(); */ BigInt toDivide; BigInt quotient; for (int i = this->size()-1; i >= 0; --i) { toDivide.digits.push_front(this->digits[i]); int q1 = toDivide.size() < r.size() ? 0 : 1; if (q1) { BigInt divisor = r; int qDiv = 0; while (divisor <= toDivide) { divisor += r; qDiv++; } if (qDiv) { toDivide -= (r * qDiv); trimLeadingZeros(toDivide); quotient.digits.push_front(qDiv); } else if (quotient.size()) { quotient.digits.push_front(0); } } else if (quotient.size()) { quotient.digits.push_front(0); } } //this->sign = carry_sign; if (r <= toDivide && quotient.digits[0] == 0) { BigInt divisor = r; int qDiv = 0; while (divisor <= toDivide) { divisor += r; qDiv++; } if (qDiv) { quotient.digits[0] = qDiv; } } else if ( quotient.size() == 0 ) { quotient.digits.push_back(0); quotient.sign = POSITIVE; } this->digits = toDivide.digits; return *this; }
BigInt& BigInt::operator -=(const BigInt& r) { /* switch(r.sign) { case NEGATIVE : if (this->sign == NEGATIVE) return *this += r; break; case POSITIVE : if (this->sign == NEGATIVE) return *this += r; break; } */ if ( this->sign == r.sign ) { if ( this->abs() >= r.abs()) { BigInt rhs(r); if (digits.size() < rhs.size()) digits.resize(rhs.size()); if (digits.size() > rhs.size()) rhs.digits.resize(digits.size()); int num = 0, carry = 0; for (unsigned int i=0; i < rhs.size(); ++i) { num = this->digits[i] - rhs.digits[i] - carry; if (num < 0) { num += base; carry = 1; } else { carry = 0; } this->digits[i] = num; } if (carry) { this->digits.push_back(carry); } trimLeadingZeros(*this); return *this; } *this = -(r - *this); return *this; } *this = *this + (-r); return *this; }
BigInt& BigInt::operator *=(int r) { for (int i=0, carry=0; i < (int)this->size() || carry; ++i) { if (i == (int)this->size()) this->digits.push_back(0); int cur = this->digits[i] * r + carry; carry = cur / this->base; this->digits[i] = cur % this->base; } trimLeadingZeros(*this); if (r < 0) this->sign = this->sign * -1; return *this; }
void maybeUnaryOperation (char *str) { const char *labelText; char buffer[BUF_SIZE]; float num2; // --- Get number in the field. labelText = gtk_label_get_text (GTK_LABEL (label)); num2 = atof (labelText); // --- Percentage? if (strcmp (str, "%") == 0) { num2 = num2 / 100; // --- Trying for 1/x? } else if (strcmp (str, "1/x") == 0) { // --- Can't divide by zero. if (num2 == 0) { return; } num2 = 1 / num2; // --- Calculate sqrt } else if (strcmp (str, "sqrt") == 0) { num2 = sqrt ((double) num2); // --- Calculate square } else if (strcmp (str, "x^2") == 0) { num2 = num2 * num2; // --- Calculate Negation } else if (strcmp (str, "+/-") == 0) { num2 = 0 - num2; prevCmd = (char) 0; lastChar = (char) 0; } /* --- Put the number back. --- */ sprintf (buffer, "%f", (float) num2); trimTrailingZeros (buffer); trimLeadingZeros (buffer); gtk_label_set_text (GTK_LABEL (label), buffer); }
void handleBinaryOperation () { char buffer[BUF_SIZE]; const char *labelText; float num2; /* --- Get number in the field. --- */ labelText = gtk_label_get_text (GTK_LABEL (label)); num2 = atof (labelText); /* --- Calculate based on previous command. --- */ switch (prevCmd) { case '+': num1 = num1 + num2; break; case '-': num1 = num1 - num2; break; case '*': num1 = num1 * num2; break; case '/': num1 = num1 / num2; break; case '=': num1 = num2; break; default: num1 = num2; break; } /* --- Put the number back. --- */ sprintf (buffer, "%f", (float) num1); trimTrailingZeros (buffer); trimLeadingZeros (buffer); gtk_label_set_text (GTK_LABEL (label), buffer); }
BigInt& BigInt::operator *=(const BigInt& r) { if (!r.size()) { this->digits.clear(); return *this; } /* int carry_sign = this->sign * r.sign; this->sign = POSITIVE; BigInt rr = r.abs(); */ int num = 0, carry = 0; std::deque<int> largeDeq, smallDeq; if (this->size() > r.size()) { largeDeq = this->digits; smallDeq = r.digits; } else { largeDeq = r.digits; smallDeq = this->digits; } // Multiply without carrying BigInt* bArray = new BigInt[smallDeq.size()]; for (unsigned int i=0; i < smallDeq.size(); ++i) { bArray[i].digits.resize(largeDeq.size()); for(unsigned int j=0; j < largeDeq.size(); ++j) { bArray[i].digits[j] = largeDeq[j] * smallDeq[i]; } } *this = bArray[0]; digits.resize(smallDeq.size() + largeDeq.size()); // Add without carrying for (unsigned int i=1; i < smallDeq.size(); ++i) { padZeros(bArray[i], i); for (unsigned int j=0; j < bArray[i].size(); ++j) { this->digits[j] += bArray[i].digits[j]; } } // Perform carrying for (unsigned int i=0; i < digits.size(); ++i) { num = digits[i] + carry; carry = num / base; num %= base; digits[i] = num; } while (carry) { this->digits.push_back(carry%base); carry /= base; } trimLeadingZeros(*this); /* if ( this->size() > 1 ) { this->sign = carry_sign; } */ delete [] bArray; return *this; }