1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 18:08:12 +00:00
serenity/Userland/Applications/Calculator/Calculator.cpp
creator1creeper1 4b2b0a4d0e Calculator: Make double construction and conversion private
At this point, the double conversions should really only be
implementation details of the KeypadValue class. Therefore,
the constructor-from double and conversion-operator-to
double of KeypadValue are made private. Instead, the
required functionality is provided by KeypadValue itself.
The internal implementation is still done using doubles.
However, this opens us up to the possibility of having
loss-free square root, inversion and division in the future.
2021-12-22 00:43:13 -08:00

124 lines
2.7 KiB
C++

/*
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Calculator.h"
#include "KeypadValue.h"
#include <AK/Assertions.h>
#include <AK/Math.h>
Calculator::Calculator()
{
}
Calculator::~Calculator()
{
}
KeypadValue Calculator::begin_operation(Operation operation, KeypadValue argument)
{
KeypadValue res = 0;
switch (operation) {
case Operation::None:
VERIFY_NOT_REACHED();
case Operation::Add:
case Operation::Subtract:
case Operation::Multiply:
case Operation::Divide:
m_saved_argument = argument;
m_operation_in_progress = operation;
return argument;
case Operation::Sqrt:
if (argument < 0) {
m_has_error = true;
return argument;
}
res = argument.sqrt();
clear_operation();
break;
case Operation::Inverse:
if (argument == 0) {
m_has_error = true;
return argument;
}
res = argument.invert();
clear_operation();
break;
case Operation::Percent:
res = argument * KeypadValue { 1, 2 }; // also known as `KeypadValue{0.01}`
break;
case Operation::ToggleSign:
res = -argument;
break;
case Operation::MemClear:
m_mem = 0;
res = argument;
break;
case Operation::MemRecall:
res = m_mem;
break;
case Operation::MemSave:
m_mem = argument;
res = argument;
break;
case Operation::MemAdd:
m_mem = m_mem + argument; //avoids the need for operator+=()
res = m_mem;
break;
}
return res;
}
KeypadValue Calculator::finish_operation(KeypadValue argument)
{
KeypadValue res = 0;
switch (m_operation_in_progress) {
case Operation::None:
return argument;
case Operation::Add:
res = m_saved_argument + argument;
break;
case Operation::Subtract:
res = m_saved_argument - argument;
break;
case Operation::Multiply:
res = m_saved_argument * argument;
break;
case Operation::Divide:
if (argument == 0) {
m_has_error = true;
return argument;
}
res = m_saved_argument / argument;
break;
case Operation::Sqrt:
case Operation::Inverse:
case Operation::Percent:
case Operation::ToggleSign:
case Operation::MemClear:
case Operation::MemRecall:
case Operation::MemSave:
case Operation::MemAdd:
VERIFY_NOT_REACHED();
}
clear_operation();
return res;
}
void Calculator::clear_operation()
{
m_operation_in_progress = Operation::None;
m_saved_argument = 0;
clear_error();
}