From 42c64309aa233884674d360374e60f3cfa8a2c88 Mon Sep 17 00:00:00 2001 From: gkamenskih Date: Mon, 21 Dec 2020 00:59:37 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9B=D0=A02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- calculator.cpp | 764 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 764 insertions(+) create mode 100644 calculator.cpp diff --git a/calculator.cpp b/calculator.cpp new file mode 100644 index 0000000..a33ea76 --- /dev/null +++ b/calculator.cpp @@ -0,0 +1,764 @@ +#include "calculator.h" +#include +#include +#include +#include +#include +#include +#include +#include + + +Calculator::Calculator(QWidget* parent) + : QWidget(parent), + f_LcNum(0), + f_currentNum(""), + f_if_curChangable(true) +{ + setMinimumSize(800, 560); + this->setWindowTitle("Standard calculator"); + MainLayout = new QGridLayout(this); + f_BtnLayoutStandard = new QGridLayout(this); + f_BtnLayoutScientExtra = new QGridLayout(this); + f_BtnLayoutScientExtraWidget = new QWidget(this); + f_BtnLayoutStandardExtrWidget = new QWidget(this); + f_BoxBtnLayout = new QHBoxLayout(this); + + f_LcNum = new QLCDNumber(12, this); + f_LcNum->setSegmentStyle(QLCDNumber::Flat); + f_LcNum->setMinimumSize(360, 80); + f_LcNum->setDigitCount(20); + + f_radioBtnStandard = new QRadioButton("Standard Calculator", this); + f_radioBtnStandard->toggle(); + f_radioBtnScient = new QRadioButton("Scientific Calculator", this); + + connect(f_radioBtnStandard, SIGNAL(toggled(bool)), this, SLOT(slotHideScient(bool))); + connect(f_radioBtnScient, SIGNAL(toggled(bool)), this, SLOT(slotShowScient(bool))); + QString ButtonsTxtStandard[4][5] = { + {"7", "8", "9", "/", "sqrt"}, + {"4", "5", "6", "*", "revs"}, + {"1", "2", "3", "-", "sqr"}, + {".", "0", "=", "+", "-x"} + }; + + QString ButtonsTxtScientExtra[4][4] = { + {"sinh", "sin", "exp", "ln"}, + {"cosh", "cos", "n!", "log"}, + {"tanh", "tan", "ysqr", "cubic sqr"}, + {"e", "pi", "cubic root", "ysqrt"} + }; + + + + for (int row = 0; row < 4; row++) + { + for (int col = 0; col < 5; col++) + { + f_BtnLayoutStandard->addWidget(createButton(ButtonsTxtStandard[row][col], 80, 60), row + 2, col); + } + } + + for (int row = 0; row < 4; row++) + { + for (int col = 0; col < 4; col++) + { + f_BtnLayoutScientExtra->addWidget(createButton(ButtonsTxtScientExtra[row][col], 80, 60), row + 2, col); + } + } + + f_BtnLayoutScientExtraWidget->setLayout(f_BtnLayoutScientExtra); + f_BtnLayoutStandardExtrWidget->setLayout(f_BtnLayoutStandard); + f_BoxBtnLayout->addWidget(f_BtnLayoutScientExtraWidget); + f_BoxBtnLayout->addWidget(f_BtnLayoutStandardExtrWidget); + MainLayout->addWidget(f_LcNum, 0, 0, 1, 8, Qt::AlignmentFlag::AlignHCenter); + MainLayout->addWidget(createButton("Clear", 100, 50), 0, 15, Qt::AlignmentFlag::AlignCenter); + + MainLayout->addWidget(f_radioBtnStandard, 1, 0, 1, 4, Qt::AlignmentFlag::AlignCenter); + MainLayout->addWidget(f_radioBtnScient, 1, 2, 1, 2, Qt::AlignmentFlag::AlignCenter); + + MainLayout->addLayout(f_BoxBtnLayout, 2, 0, 4, 9, Qt::AlignmentFlag::AlignCenter); + + f_BtnLayoutScientExtraWidget->hide(); + this->setLayout(MainLayout); + resize(500, 400); +} + +QPushButton* Calculator::createButton(const QString& pStr, size_t pHoriz, size_t pVert) +{ + QPushButton* new_PBtn = new QPushButton(pStr); + new_PBtn->setMinimumSize(pHoriz, pVert); + connect(new_PBtn, SIGNAL(clicked()), this, SLOT(slotButtonClicked())); + return new_PBtn; +} + +Calculator::~Calculator() +{} + +void Calculator::calctr() +{ + if (f_opStack.size() < 2) + return; + + if (f_opStack.size() == 2) + { + QString operation = f_opStack.pop(); + double operand = f_opStack.pop().toDouble(); + qDebug() << operand << operation << " 0 if binary"; + + if (operation == "revs") + { + if (operand == 0) + { + f_LcNum->display("Error"); + qDebug() << "Error"; + } + else + f_LcNum->display(1 / operand); + qDebug() << 1 / operand; + } + + if (operation == "sqr") + { + f_LcNum->display(operand * operand); + qDebug() << operand * operand; + } + + if (operation == "sqrt") + { + f_LcNum->display(sqrt(operand)); + qDebug() << sqrt(operand); + } + + if (operation == "-x") + { + f_LcNum->display(-operand); + qDebug() << -operand; + } + + if (operation == "cubic root") + { + double tt = 1 / 3.0; + f_LcNum->display(qPow(operand, tt)); + qDebug() << qPow(operand, tt); + } + + if (operation == "cubic sqr") + { + f_LcNum->display(operand * operand * operand); + qDebug() << operand * operand * operand; + } + + if (operation == "n!") + { + int res = 1; + int oper = static_cast(operand); + if (oper < 1) + { + f_LcNum->display("Error"); + return; + } + else + { + while (oper > 1) + { + res *= oper; + oper--; + } + } + f_LcNum->display(res); + qDebug() << res; + } + + if (operation == "+" || operation == "-") + { + f_LcNum->display(operand); + qDebug() << operand; + } + + if (operation == "*") + { + f_LcNum->display(0); + qDebug() << 0; + } + + if (operation == "/") + { + f_LcNum->display("Error"); + qDebug() << "Error"; + } + + if (operation == "log") + { + f_LcNum->display("Error"); + qDebug() << "Error"; + } + + if (operation == "sin") + { + f_LcNum->display(qSin(operand)); + qDebug() << qSin(operand); + } + + if (operation == "sinh") + { + f_LcNum->display(qAsin(operand)); + qDebug() << qAsin(operand); + } + + if (operation == "cos") + { + f_LcNum->display(qCos(operand)); + qDebug() << qCos(operand); + } + + if (operation == "cosh") + { + f_LcNum->display(qAcos(operand)); + qDebug() << qAcos(operand); + } + + if (operation == "tanh") + { + f_LcNum->display(qAtan(operand)); + qDebug() << qAtan(operand); + } + + if (operation == "tan") + { + f_LcNum->display(qTan(operand)); + qDebug() << qTan(operand); + } + + if (operation == "exp") + { + f_LcNum->display(qExp(operand)); + qDebug() << qExp(operand); + } + + if (operation == "ln") + { + f_LcNum->display(qLn(operand)); + qDebug() << qLn(operand); + } + + if (operation == "ysqr") + { + f_LcNum->display(1); + qDebug() << 1; + } + + if (operation == "ysqrt") + { + f_LcNum->display("Error"); + qDebug() << "Error"; + } + + + } + else if (f_opStack.size() == 3) + { + + double operand2 = f_opStack.pop().toDouble(); + QString operation = f_opStack.pop(); + double operand1 = f_opStack.pop().toDouble(); + + qDebug() << operand1 << operation << operand2 << ":"; + + if (operation == "+") + { + f_LcNum->display(operand1 + operand2); + qDebug() << operand1 + operand2; + } + + if (operation == "-") + { + f_LcNum->display(operand1 - operand2); + qDebug() << operand1 - operand2; + } + + if (operation == "*") + { + f_LcNum->display(operand1 * operand2); + qDebug() << operand1 * operand2; + } + + if (operation == "/") + { + f_LcNum->display(operand1 / operand2); + qDebug() << operand1 / operand2; + } + + if (operation == "log") + { + f_LcNum->display(qLn(operand1) / qLn(operand2)); + qDebug() << qLn(operand1) / qLn(operand2); + } + + if (operation == "ysqr") + { + f_LcNum->display(qPow(operand1, operand2)); + qDebug() << qPow(operand1, operand2); + } + + if (operation == "ysqrt") + { + f_LcNum->display(qPow(operand1, 1.0 / operand2)); + qDebug() << qPow(operand1, 1.0 / operand2); + } + } + else if (f_opStack.size() == 5) + { + double operand3 = f_opStack.pop().toDouble(); + QString operation2 = f_opStack.pop(); + double operand2 = f_opStack.pop().toDouble(); + QString operation1 = f_opStack.pop(); + double operand1 = f_opStack.pop().toDouble(); + double midRes; + + qDebug() << operand1 << operation1 << operand2 << operation2 << operand3 << ":"; + if (operation2 == "*") + { + midRes = operand2 * operand3; + qDebug() << "midRes = " << operand2 * operand3; + } + + if (operation1 == "+") + { + f_LcNum->display(operand1 + midRes); + qDebug() << operand1 + midRes; + } + + if (operation1 == "-") + { + f_LcNum->display(operand1 - midRes); + qDebug() << operand1 - midRes; + } + + if (operation1 == "*") + { + f_LcNum->display(operand1 * midRes); + qDebug() << operand1 * midRes; + } + + if (operation1 == "/") + { + f_LcNum->display(operand1 / midRes); + qDebug() << operand1 / midRes; + } + + if (operation1 == "log") + { + f_LcNum->display(qLn(operand1) / qLn(midRes)); + qDebug() << qLn(operand1) / qLn(midRes); + } + + if (operation1 == "ysqr") + { + f_LcNum->display(qPow(operand1, midRes)); + qDebug() << qPow(operand1, midRes); + } + + if (operation1 == "ysqrt") + { + f_LcNum->display(qPow(operand1, 1.0 / midRes)); + qDebug() << qPow(operand1, 1.0 / midRes); + } + + if (operation2 == "/") + { + midRes = operand2 / operand3; + qDebug() << "midRes = " << operand2 / operand3; + } + + if (operation2 == "log") + { + midRes = qLn(operand2) / qLn(operand3); + qDebug() << "midRes = " << qLn(operand2) / qLn(operand3); + } + + if (operation2 == "ysqr") + { + midRes = qPow(operand2, operand3); + qDebug() << "midRes = " << qPow(operand2, operand3); + } + + if (operation2 == "ysqrt") + { + midRes = qPow(operand2, 1.0 / operand3); + qDebug() << "midRes = " << qPow(operand2, 1.0 / operand3); + } + } +} + +void Calculator::slotHideScient(bool p_is) +{ + if (p_is) + { + this->setWindowTitle("Standard Calculator"); + f_BtnLayoutScientExtraWidget->hide(); + + setMinimumSize(600, 450); + resize(600, 450); + qDebug() << "Resize (600, 450)"; + f_LcNum->setMinimumSize(370, 60); + f_LcNum->setDigitCount(20); + } +} + +void Calculator::slotShowScient(bool p_is) +{ + if (p_is) + { + this->setWindowTitle("Scientific Calculator"); + f_BtnLayoutScientExtraWidget->show(); + + setMinimumSize(900, 450); + resize(900, 450); + + qDebug() << "Resize (900, 450)"; + f_LcNum->setMinimumSize(650, 60); + f_LcNum->setDigitCount(35); + } +} + + +void Calculator::slotButtonClicked() +{ + QPushButton* s = dynamic_cast(sender()); + QString input; + if (s) + input = s->text(); + else + return; + + QString input; + if (s) + input = s->text(); + else + input = ""; + + qDebug() << "Just now pressed: " << input; + + if (input == "Clear") + { + f_opStack.clear(); + f_currentNum = ""; + f_LcNum->display(0); + return; + } + + if (input == "C") + { + if (f_currentNum != "") + { + f_currentNum = ""; + f_LcNum->display(0); + return; + } + else + { + f_opStack.clear(); + f_LcNum->display(0); + return; + } + } + + if (input.contains(QRegExp("[0-9]"))) + { + if (f_if_curChangable) + { + if (input == "0" && f_currentNum == "") + { + f_LcNum->display(0); + return; + } + f_currentNum += input; + f_LcNum->display(f_currentNum); + return; + } + else + { + f_if_curChangable = true; + if (input == "0") + { + f_currentNum = ""; + f_LcNum->display(0); + return; + } + f_currentNum = input; + f_LcNum->display(f_currentNum); + return; + } + } + else if (input == ".") + { + if (f_currentNum == "") + { + f_currentNum += "0."; + f_LcNum->display(f_currentNum); + return; + } + else + { + if (f_if_curChangable) + { + if (f_currentNum.contains('.')) + { + f_currentNum = "0."; + f_LcNum->display(f_currentNum); + return; + } + f_currentNum += input; + f_LcNum->display(f_currentNum); + return; + } + else + { + f_if_curChangable = true; + f_currentNum = "0."; + f_LcNum->display(f_currentNum); + return; + } + } + } + else if (NumND.contains(input)) + { + if (input == "e") + { + f_currentNum = QString::number(qExp(1)); + f_if_curChangable = false; + f_LcNum->display(f_currentNum); + return; + } + else + { + f_currentNum = QString::number(PI); + f_if_curChangable = false; + f_LcNum->display(f_currentNum); + return; + } + } + else + { + if (input == "=") + { + if (f_opStack.size() == 0) + { + return; + } + else if (f_opStack.size() == 2) + { + if (f_currentNum == "") + { + calctr(); + return; + } + else + { + f_opStack.push_back(f_currentNum); + calctr(); + f_opStack.clear(); + f_currentNum = ""; + return; + } + } + else + { + if (f_currentNum == "") + { + f_opStack.pop_back(); + calctr(); + f_opStack.clear(); + return; + } + else + { + f_opStack.push_back(f_currentNum); + f_currentNum = ""; + calctr(); + f_opStack.clear(); + return; + } + } + } + else + { + if (f_opStack.size() == 0) + { + if (f_currentNum == "") + { + f_opStack.push_back(QString::number(f_LcNum->value())); + f_opStack.push_back(input); + if (UnOp.contains(input)) + { + calctr(); + f_opStack.clear(); + return; + } + return; + } + else + { + f_opStack.push_back(f_currentNum); + f_currentNum = ""; + f_opStack.push_back(input); + if (UnOp.contains(input)) + { + calctr(); + f_opStack.clear(); + return; + } + return; + } + } + else if (f_opStack.size() == 2) + { + if (f_currentNum == "") + { + f_opStack.pop_back(); + f_opStack.push_back(input); + if (UnOp.contains(input)) + { + calctr(); + f_opStack.clear(); + return; + } + return; + } + else + { + QString tec_oper; + tec_oper = f_opStack.pop(); + if (OpToCountimmediately.contains(tec_oper) || SumOp.contains(input)) + { + f_opStack.push_back(tec_oper); + f_opStack.push_back(f_currentNum); + f_currentNum = ""; + calctr(); + f_opStack.clear(); + f_opStack.push_back(QString::number(f_LcNum->value())); + f_opStack.push_back(input); + return; + } + else + { + if (UnOp.contains(input)) + { + QString tec_f_operand; + tec_f_operand = f_opStack.pop(); + + f_opStack.push_back(f_currentNum); + f_opStack.push_back(input); + calctr(); + f_opStack.clear(); + f_opStack.push_back(tec_f_operand); + f_opStack.push_back(tec_oper); + f_currentNum = QString::number(f_LcNum->value()); + f_if_curChangable = false; + return; + } + else + { + f_opStack.push_back(f_currentNum); + f_currentNum = ""; + f_opStack.push_back(input); + return; + } + } + } + } + else + { + if (f_currentNum == "") + { + f_opStack.pop_back(); + if (UnOp.contains(input)) + { + QString tec_f_operand; + QString tec_s_operand; + QString tec_oper; + tec_s_operand = f_opStack.pop(); + tec_oper = f_opStack.pop(); + tec_f_operand = f_opStack.pop(); + f_opStack.push_back(tec_s_operand); + f_opStack.push_back(input); + calctr(); + f_opStack.clear(); + f_opStack.push_back(tec_f_operand); + f_opStack.push_back(tec_oper); + f_currentNum = QString::number(f_LcNum->value()); + return; + } + else + { + f_opStack.push_back(input); + return; + } + } + else + { + if (UnOp.contains(input)) + { + QString tec_f_operand; + QString tec_s_operand; + QString tec_oper1; + QString tec_oper2; + + tec_oper2 = f_opStack.pop(); + tec_s_operand = f_opStack.pop(); + tec_oper1 = f_opStack.pop(); + tec_f_operand = f_opStack.pop(); + + f_opStack.push_back(f_currentNum); + f_opStack.push_back(input); + calctr(); + f_opStack.clear(); + f_currentNum = QString::number(f_LcNum->value()); + f_if_curChangable = false; + + f_opStack.push_back(tec_f_operand); + f_opStack.push_back(tec_oper1); + f_opStack.push_back(tec_s_operand); + f_opStack.push_back(tec_oper2); + return; + } + else + { + if (SumOp.contains(input)) + { + f_opStack.push_back(f_currentNum); + f_currentNum = ""; + calctr(); + f_opStack.clear(); + f_opStack.push_back(QString::number(f_LcNum->value())); + f_opStack.push_back(input); + return; + } + QString tec_f_operand; + QString tec_s_operand; + QString tec_oper1; + QString tec_oper2; + + tec_oper2 = f_opStack.pop(); + tec_s_operand = f_opStack.pop(); + tec_oper1 = f_opStack.pop(); + tec_f_operand = f_opStack.pop(); + + f_opStack.push_back(tec_s_operand); + f_opStack.push_back(tec_oper2); + f_opStack.push_back(f_currentNum); + calctr(); + f_opStack.clear(); + f_opStack.push_back(tec_f_operand); + f_opStack.push_back(tec_oper1); + f_opStack.push_back(QString::number(f_LcNum->value())); + f_opStack.push_back(input); + f_currentNum = ""; + return; + } + } + } + } + } +} -- GitLab