mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-22 06:13:14 -07:00
Fix C++ warnings
Check for exactly 1 before using the singular noun, rather than check for greater than 1, just in case somehow the variable being evaluated ends up as 0 In addition, should this code ever be refactored in such a way that the check to 0 is changed, this will ensure the end result does not change. In addition, it is naturally immediately apparent to the developers what is going on, potentially enhancing maintainability. Additionally, make bitwise operations more obvious in their intentions. Fix unused parameters in functions by using [[maybe_unused]]
This commit is contained in:
parent
f27bdba85a
commit
f5662250cf
82 changed files with 1322 additions and 1390 deletions
|
@ -56,11 +56,11 @@ bool CalcInput::TryToggleSign(bool isIntegerMode, wstring_view maxNumStr)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, int32_t wordBitWidth, int maxDigits)
|
||||
bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, uint32_t wordBitWidth, int maxDigits)
|
||||
{
|
||||
// Convert from an integer into a character
|
||||
// This includes both normal digits and alpha 'digits' for radixes > 10
|
||||
auto chDigit = static_cast<wchar_t>((value < 10) ? (L'0' + value) : (L'A' + value - 10));
|
||||
auto chDigit = static_cast<wchar_t>(value < 10 ? L'0' + value : L'A' + value - 10);
|
||||
|
||||
CalcNumSec* pNumSec;
|
||||
size_t maxCount;
|
||||
|
@ -89,7 +89,7 @@ bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMo
|
|||
}
|
||||
|
||||
// Ignore leading zeros
|
||||
if (pNumSec->IsEmpty() && (value == 0))
|
||||
if (pNumSec->IsEmpty() && value == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -108,17 +108,16 @@ bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMo
|
|||
|
||||
if (radix == 8)
|
||||
{
|
||||
switch (wordBitWidth % 3)
|
||||
const auto modResult = wordBitWidth % 3;
|
||||
if (modResult == 1)
|
||||
{
|
||||
case 1:
|
||||
// in 16 or 64bit word size, if the first digit is a 1 we can enter 6 (16bit) or 22 (64bit) digits
|
||||
allowExtraDigit = (pNumSec->value.front() == L'1');
|
||||
break;
|
||||
|
||||
case 2:
|
||||
allowExtraDigit = pNumSec->value.front() == L'1';
|
||||
}
|
||||
else if (modResult == 2)
|
||||
{
|
||||
// in 8 or 32bit word size, if the first digit is a 3 or less we can enter 3 (8bit) or 11 (32bit) digits
|
||||
allowExtraDigit = (pNumSec->value.front() <= L'3');
|
||||
break;
|
||||
allowExtraDigit = pNumSec->value.front() <= L'3';
|
||||
}
|
||||
}
|
||||
else if (radix == 10)
|
||||
|
@ -137,14 +136,14 @@ bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMo
|
|||
|
||||
// If cmpResult == 0:
|
||||
// Undecided still. The case when max is "127", and current number is "12". Look for the new number being 7 or less to allow
|
||||
auto cmpResult = pNumSec->value.compare(0, wstring::npos, maxNumStr, 0, pNumSec->value.size());
|
||||
const auto cmpResult = pNumSec->value.compare(0, wstring::npos, maxNumStr, 0, pNumSec->value.size());
|
||||
if (cmpResult < 0)
|
||||
{
|
||||
allowExtraDigit = true;
|
||||
}
|
||||
else if (cmpResult == 0)
|
||||
{
|
||||
auto lastChar = maxNumStr[pNumSec->value.size()];
|
||||
const auto lastChar = maxNumStr[pNumSec->value.size()];
|
||||
if (chDigit <= lastChar)
|
||||
{
|
||||
allowExtraDigit = true;
|
||||
|
@ -189,7 +188,7 @@ bool CalcInput::TryAddDecimalPt()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CalcInput::HasDecimalPt()
|
||||
bool CalcInput::HasDecimalPt() const
|
||||
{
|
||||
return m_hasDecimal;
|
||||
}
|
||||
|
@ -253,8 +252,11 @@ void CalcInput::Backspace()
|
|||
|
||||
void CalcInput::SetDecimalSymbol(wchar_t decSymbol)
|
||||
{
|
||||
if (m_decSymbol != decSymbol)
|
||||
if (m_decSymbol == decSymbol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_decSymbol = decSymbol;
|
||||
|
||||
if (m_hasDecimal)
|
||||
|
@ -262,20 +264,19 @@ void CalcInput::SetDecimalSymbol(wchar_t decSymbol)
|
|||
// Change to new decimal pt
|
||||
m_base.value[m_decPtIndex] = m_decSymbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CalcInput::IsEmpty()
|
||||
bool CalcInput::IsEmpty() const
|
||||
{
|
||||
return m_base.IsEmpty() && !m_hasExponent && m_exponent.IsEmpty() && !m_hasDecimal;
|
||||
}
|
||||
|
||||
wstring CalcInput::ToString(uint32_t radix)
|
||||
wstring CalcInput::ToString(uint32_t radix) const
|
||||
{
|
||||
// In theory both the base and exponent could be C_NUM_MAX_DIGITS long.
|
||||
if ((m_base.value.size() > MAX_STRLEN) || (m_hasExponent && m_exponent.value.size() > MAX_STRLEN))
|
||||
if (m_base.value.size() > MAX_STRLEN || m_hasExponent && m_exponent.value.size() > MAX_STRLEN)
|
||||
{
|
||||
return wstring();
|
||||
return {};
|
||||
}
|
||||
|
||||
wstring result;
|
||||
|
@ -302,8 +303,8 @@ wstring CalcInput::ToString(uint32_t radix)
|
|||
result += m_decSymbol;
|
||||
}
|
||||
|
||||
result += ((radix == 10) ? L'e' : L'^');
|
||||
result += (m_exponent.IsNegative() ? L'-' : L'+');
|
||||
result += radix == 10 ? L'e' : L'^';
|
||||
result += m_exponent.IsNegative() ? L'-' : L'+';
|
||||
|
||||
if (m_exponent.IsEmpty())
|
||||
{
|
||||
|
@ -318,13 +319,13 @@ wstring CalcInput::ToString(uint32_t radix)
|
|||
// Base and Exp can each be up to C_NUM_MAX_DIGITS in length, plus 4 characters for sign, dec, exp, and expSign.
|
||||
if (result.size() > C_NUM_MAX_DIGITS * 2 + 4)
|
||||
{
|
||||
return wstring();
|
||||
return {};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Rational CalcInput::ToRational(uint32_t radix, int32_t precision)
|
||||
Rational CalcInput::ToRational(uint32_t radix, int32_t precision) const
|
||||
{
|
||||
PRAT rat = StringToRat(m_base.IsNegative(), m_base.value, m_exponent.IsNegative(), m_exponent.value, radix, precision);
|
||||
if (rat == nullptr)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
bool IsOpInRange(OpCode op, uint32_t x, uint32_t y)
|
||||
{
|
||||
return ((op >= x) && (op <= y));
|
||||
return op >= x && op <= y;
|
||||
}
|
||||
|
||||
bool IsBinOpCode(OpCode opCode)
|
||||
|
@ -18,7 +18,7 @@ bool IsBinOpCode(OpCode opCode)
|
|||
// of it and catch it themselves or not needing this
|
||||
bool IsUnaryOpCode(OpCode opCode)
|
||||
{
|
||||
return (IsOpInRange(opCode, IDC_UNARYFIRST, IDC_UNARYLAST) || IsOpInRange(opCode, IDC_UNARYEXTENDEDFIRST, IDC_UNARYEXTENDEDLAST));
|
||||
return IsOpInRange(opCode, IDC_UNARYFIRST, IDC_UNARYLAST) || IsOpInRange(opCode, IDC_UNARYEXTENDEDFIRST, IDC_UNARYEXTENDEDLAST);
|
||||
}
|
||||
|
||||
bool IsDigitOpCode(OpCode opCode)
|
||||
|
@ -49,8 +49,8 @@ bool IsGuiSettingOpCode(OpCode opCode)
|
|||
case IDC_MPLUS:
|
||||
case IDC_MMINUS:
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
// most of the commands
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ using namespace CalcEngine;
|
|||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
static void Truncate(vector<T>& v, unsigned int index)
|
||||
void Truncate(vector<T>& v, unsigned int index)
|
||||
{
|
||||
if (index >= v.size())
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ void CHistoryCollector::ReinitHistory()
|
|||
// Constructor
|
||||
// Can throw Out of memory error
|
||||
CHistoryCollector::CHistoryCollector(ICalcDisplay* pCalcDisplay, std::shared_ptr<IHistoryDisplay> pHistoryDisplay, wchar_t decimalSymbol)
|
||||
: m_pHistoryDisplay(pHistoryDisplay)
|
||||
: m_pHistoryDisplay(std::move(pHistoryDisplay))
|
||||
, m_pCalcDisplay(pCalcDisplay)
|
||||
, m_iCurLineHistStart(-1)
|
||||
, m_decimalSymbol(decimalSymbol)
|
||||
|
@ -66,13 +66,13 @@ CHistoryCollector::~CHistoryCollector()
|
|||
|
||||
void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& rat, bool fRepetition)
|
||||
{
|
||||
std::shared_ptr<std::vector<int>> commands = std::make_shared<vector<int>>();
|
||||
auto commands = std::make_shared<vector<int>>();
|
||||
// Check for negate
|
||||
bool fNegative = (numStr[0] == L'-');
|
||||
bool fNegative = numStr[0] == L'-';
|
||||
bool fSciFmt = false;
|
||||
bool fDecimal = false;
|
||||
|
||||
for (size_t i = (fNegative ? 1 : 0); i < numStr.length(); i++)
|
||||
for (size_t i = fNegative ? 1 : 0; i < numStr.length(); i++)
|
||||
{
|
||||
if (numStr[i] == m_decimalSymbol)
|
||||
{
|
||||
|
@ -98,8 +98,7 @@ void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& ra
|
|||
// Number
|
||||
else
|
||||
{
|
||||
int num = static_cast<int>(numStr[i]) - ASCII_0;
|
||||
num += IDC_0;
|
||||
int num = static_cast<int>(numStr[i]) - ASCII_0 + IDC_0;
|
||||
commands->push_back(num);
|
||||
}
|
||||
}
|
||||
|
@ -143,19 +142,19 @@ void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool isIntegerMode, bool
|
|||
// This is expected to be called when a binary op in the last say 1+2+ is changing to another one say 1+2* (+ changed to *)
|
||||
// It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new
|
||||
// one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^)
|
||||
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode)
|
||||
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntegerMode)
|
||||
{
|
||||
TruncateEquationSzFromIch(m_lastBinOpStartIndex);
|
||||
if (fPrecInvToHigher)
|
||||
{
|
||||
EnclosePrecInversionBrackets();
|
||||
}
|
||||
AddBinOpToHistory(nOpCode, isIntgerMode);
|
||||
AddBinOpToHistory(nOpCode, isIntegerMode);
|
||||
}
|
||||
|
||||
void CHistoryCollector::PushLastOpndStart(int ichOpndStart)
|
||||
{
|
||||
int ich = (ichOpndStart == -1) ? m_lastOpStartIndex : ichOpndStart;
|
||||
int ich = ichOpndStart == -1 ? m_lastOpStartIndex : ichOpndStart;
|
||||
|
||||
if (m_curOperandIndex < static_cast<int>(m_operandIndices.size()))
|
||||
{
|
||||
|
@ -174,8 +173,7 @@ void CHistoryCollector::PopLastOpndStart()
|
|||
void CHistoryCollector::AddOpenBraceToHistory()
|
||||
{
|
||||
AddCommand(std::make_shared<CParentheses>(IDC_OPENP));
|
||||
int ichOpndStart = IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_OPENP), -1);
|
||||
PushLastOpndStart(ichOpndStart);
|
||||
PushLastOpndStart(IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_OPENP), -1));
|
||||
|
||||
SetExpressionDisplay();
|
||||
m_lastBinOpStartIndex = -1;
|
||||
|
@ -195,15 +193,15 @@ void CHistoryCollector::AddCloseBraceToHistory()
|
|||
void CHistoryCollector::EnclosePrecInversionBrackets()
|
||||
{
|
||||
// Top of the Opnd starts index or 0 is nothing is in top
|
||||
int ichStart = (m_curOperandIndex > 0) ? m_operandIndices[m_curOperandIndex - 1] : 0;
|
||||
int ichStart = m_curOperandIndex > 0 ? m_operandIndices[m_curOperandIndex - 1] : 0;
|
||||
|
||||
InsertSzInEquationSz(CCalcEngine::OpCodeToString(IDC_OPENP), -1, ichStart);
|
||||
IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_CLOSEP), -1);
|
||||
}
|
||||
|
||||
bool CHistoryCollector::FOpndAddedToHistory()
|
||||
bool CHistoryCollector::FOpndAddedToHistory() const
|
||||
{
|
||||
return (-1 != m_lastOpStartIndex);
|
||||
return m_lastOpStartIndex != -1;
|
||||
}
|
||||
|
||||
// AddUnaryOpToHistory
|
||||
|
@ -244,7 +242,7 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, AngleType an
|
|||
angleOpCode = CalculationManager::Command::CommandGRAD;
|
||||
}
|
||||
|
||||
int command = nOpCode;
|
||||
int command;
|
||||
switch (nOpCode)
|
||||
{
|
||||
case IDC_SIN:
|
||||
|
@ -330,10 +328,9 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, AngleType an
|
|||
// history of equations
|
||||
void CHistoryCollector::CompleteHistoryLine(wstring_view numStr)
|
||||
{
|
||||
if (nullptr != m_pHistoryDisplay)
|
||||
if (m_pHistoryDisplay != nullptr)
|
||||
{
|
||||
unsigned int addedItemIndex = m_pHistoryDisplay->AddToHistory(m_spTokens, m_spCommands, numStr);
|
||||
m_pCalcDisplay->OnHistoryItemAdded(addedItemIndex);
|
||||
m_pCalcDisplay->OnHistoryItemAdded(m_pHistoryDisplay->AddToHistory(m_spTokens, m_spCommands, numStr));
|
||||
}
|
||||
|
||||
m_spTokens = nullptr;
|
||||
|
@ -354,16 +351,18 @@ void CHistoryCollector::CompleteEquation(std::wstring_view numStr)
|
|||
|
||||
void CHistoryCollector::ClearHistoryLine(wstring_view errStr)
|
||||
{
|
||||
if (errStr.empty()) // in case of error let the display stay as it is
|
||||
if (!errStr.empty()) // in case of error let the display stay as it is
|
||||
{
|
||||
if (nullptr != m_pCalcDisplay)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
{
|
||||
m_pCalcDisplay->SetExpressionDisplay(
|
||||
std::make_shared<std::vector<std::pair<std::wstring, int>>>(), std::make_shared<std::vector<std::shared_ptr<IExpressionCommand>>>());
|
||||
}
|
||||
m_iCurLineHistStart = -1; // It will get recomputed at the first Opnd
|
||||
ReinitHistory();
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the given string psz to the globally maintained current equation string at the end.
|
||||
|
@ -380,25 +379,25 @@ int CHistoryCollector::IchAddSzToEquationSz(wstring_view str, int icommandIndex)
|
|||
}
|
||||
|
||||
// Inserts a given string into the global m_pszEquation at the given index ich taking care of reallocations etc.
|
||||
void CHistoryCollector::InsertSzInEquationSz(wstring_view str, int icommandIndex, int ich)
|
||||
void CHistoryCollector::InsertSzInEquationSz(wstring_view str, int icommandIndex, int ich) const
|
||||
{
|
||||
m_spTokens->emplace(m_spTokens->begin() + ich, wstring(str), icommandIndex);
|
||||
}
|
||||
|
||||
// Chops off the current equation string from the given index
|
||||
void CHistoryCollector::TruncateEquationSzFromIch(int ich)
|
||||
void CHistoryCollector::TruncateEquationSzFromIch(int ich) const
|
||||
{
|
||||
// Truncate commands
|
||||
int minIdx = -1;
|
||||
unsigned int nTokens = static_cast<unsigned int>(m_spTokens->size());
|
||||
auto nTokens = m_spTokens->size();
|
||||
|
||||
for (unsigned int i = ich; i < nTokens; i++)
|
||||
for (size_t i = ich; i < nTokens; i++)
|
||||
{
|
||||
const auto& currentPair = (*m_spTokens)[i];
|
||||
int curTokenId = currentPair.second;
|
||||
const int curTokenId = currentPair.second;
|
||||
if (curTokenId != -1)
|
||||
{
|
||||
if ((minIdx != -1) || (curTokenId < minIdx))
|
||||
if (minIdx != -1 || curTokenId < minIdx)
|
||||
{
|
||||
minIdx = curTokenId;
|
||||
Truncate(*m_spCommands, minIdx);
|
||||
|
@ -410,9 +409,9 @@ void CHistoryCollector::TruncateEquationSzFromIch(int ich)
|
|||
}
|
||||
|
||||
// Adds the m_pszEquation into the running history text
|
||||
void CHistoryCollector::SetExpressionDisplay()
|
||||
void CHistoryCollector::SetExpressionDisplay() const
|
||||
{
|
||||
if (nullptr != m_pCalcDisplay)
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
{
|
||||
m_pCalcDisplay->SetExpressionDisplay(m_spTokens, m_spCommands);
|
||||
}
|
||||
|
@ -465,13 +464,13 @@ void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
|
|||
}
|
||||
|
||||
// Update the commands corresponding to the passed string Number
|
||||
std::shared_ptr<std::vector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr)
|
||||
std::shared_ptr<std::vector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr) const
|
||||
{
|
||||
std::shared_ptr<std::vector<int>> commands = std::make_shared<std::vector<int>>();
|
||||
// Check for negate
|
||||
bool fNegative = (numStr[0] == L'-');
|
||||
bool fNegative = numStr[0] == L'-';
|
||||
|
||||
for (size_t i = (fNegative ? 1 : 0); i < numStr.length(); i++)
|
||||
for (size_t i = fNegative ? 1 : 0; i < numStr.length(); i++)
|
||||
{
|
||||
if (numStr[i] == m_decimalSymbol)
|
||||
{
|
||||
|
@ -492,8 +491,7 @@ std::shared_ptr<std::vector<int>> CHistoryCollector::GetOperandCommandsFromStrin
|
|||
// Number
|
||||
else
|
||||
{
|
||||
int num = static_cast<int>(numStr[i]) - ASCII_0;
|
||||
num += IDC_0;
|
||||
int num = static_cast<int>(numStr[i]) - ASCII_0 + IDC_0;
|
||||
commands->push_back(num);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,9 @@ namespace CalcEngine
|
|||
Number::Number(PNUMBER p) noexcept
|
||||
: m_sign{ p->sign }
|
||||
, m_exp{ p->exp }
|
||||
, m_mantissa{}
|
||||
{
|
||||
m_mantissa.reserve(p->cdigit);
|
||||
copy(p->mant, p->mant + p->cdigit, back_inserter(m_mantissa));
|
||||
copy_n(p->mant, p->cdigit, back_inserter(m_mantissa));
|
||||
}
|
||||
|
||||
PNUMBER Number::ToPNUMBER() const
|
||||
|
|
|
@ -7,8 +7,7 @@ using namespace std;
|
|||
namespace CalcEngine
|
||||
{
|
||||
Rational::Rational() noexcept
|
||||
: m_p{}
|
||||
, m_q{ 1, 0, { 1 } }
|
||||
: m_q{ 1, 0, { 1 } }
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -24,15 +23,15 @@ namespace CalcEngine
|
|||
m_q = Number(1, qExp, { 1 });
|
||||
}
|
||||
|
||||
Rational::Rational(Number const& p, Number const& q) noexcept
|
||||
: m_p{ p }
|
||||
, m_q{ q }
|
||||
Rational::Rational(Number p, Number q) noexcept
|
||||
: m_p{ std::move(p) }
|
||||
, m_q{ std::move(q) }
|
||||
{
|
||||
}
|
||||
|
||||
Rational::Rational(int32_t i)
|
||||
{
|
||||
PRAT pr = i32torat(static_cast<int32_t>(i));
|
||||
PRAT pr = i32torat(i);
|
||||
|
||||
m_p = Number{ pr->pp };
|
||||
m_q = Number{ pr->pq };
|
||||
|
@ -42,7 +41,7 @@ namespace CalcEngine
|
|||
|
||||
Rational::Rational(uint32_t ui)
|
||||
{
|
||||
PRAT pr = Ui32torat(static_cast<uint32_t>(ui));
|
||||
PRAT pr = Ui32torat(ui);
|
||||
|
||||
m_p = Number{ pr->pp };
|
||||
m_q = Number{ pr->pq };
|
||||
|
@ -52,8 +51,8 @@ namespace CalcEngine
|
|||
|
||||
Rational::Rational(uint64_t ui)
|
||||
{
|
||||
uint32_t hi = (uint32_t)(((ui) >> 32) & 0xffffffff);
|
||||
uint32_t lo = (uint32_t)ui;
|
||||
uint32_t hi = static_cast<uint32_t>(ui >> 32);
|
||||
uint32_t lo = static_cast<uint32_t>(ui & 0xffffffff);
|
||||
|
||||
Rational temp = (Rational{ hi } << 32) | lo;
|
||||
|
||||
|
@ -106,7 +105,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -129,7 +128,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -152,7 +151,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -175,7 +174,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -205,7 +204,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -228,7 +227,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -251,7 +250,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -274,7 +273,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -296,7 +295,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -318,7 +317,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
*this = Rational{ lhsRat };
|
||||
|
@ -399,7 +398,7 @@ namespace CalcEngine
|
|||
PRAT lhsRat = lhs.ToPRAT();
|
||||
PRAT rhsRat = rhs.ToPRAT();
|
||||
|
||||
bool result = false;
|
||||
bool result;
|
||||
try
|
||||
{
|
||||
result = rat_equ(lhsRat, rhsRat, RATIONAL_PRECISION);
|
||||
|
@ -408,7 +407,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
destroyrat(lhsRat);
|
||||
|
@ -427,7 +426,7 @@ namespace CalcEngine
|
|||
PRAT lhsRat = lhs.ToPRAT();
|
||||
PRAT rhsRat = rhs.ToPRAT();
|
||||
|
||||
bool result = false;
|
||||
bool result;
|
||||
try
|
||||
{
|
||||
result = rat_lt(lhsRat, rhsRat, RATIONAL_PRECISION);
|
||||
|
@ -436,7 +435,7 @@ namespace CalcEngine
|
|||
{
|
||||
destroyrat(lhsRat);
|
||||
destroyrat(rhsRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
destroyrat(lhsRat);
|
||||
|
@ -460,19 +459,19 @@ namespace CalcEngine
|
|||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
wstring Rational::ToString(uint32_t radix, NumberFormat fmt, int32_t precision) const
|
||||
wstring Rational::ToString(uint32_t radix, NumberFormat format, int32_t precision) const
|
||||
{
|
||||
PRAT rat = this->ToPRAT();
|
||||
wstring result{};
|
||||
wstring result;
|
||||
|
||||
try
|
||||
{
|
||||
result = RatToString(rat, fmt, radix, precision);
|
||||
result = RatToString(rat, format, radix, precision);
|
||||
}
|
||||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(rat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
destroyrat(rat);
|
||||
|
@ -491,7 +490,7 @@ namespace CalcEngine
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(rat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
destroyrat(rat);
|
||||
|
|
|
@ -16,7 +16,7 @@ Rational RationalMath::Frac(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -35,7 +35,7 @@ Rational RationalMath::Integer(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -58,7 +58,7 @@ Rational RationalMath::Pow(Rational const& base, Rational const& pow)
|
|||
{
|
||||
destroyrat(baseRat);
|
||||
destroyrat(powRat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ baseRat };
|
||||
|
@ -83,7 +83,7 @@ Rational RationalMath::Fact(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -103,7 +103,7 @@ Rational RationalMath::Exp(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -123,7 +123,7 @@ Rational RationalMath::Log(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -158,7 +158,7 @@ Rational RationalMath::Sin(Rational const& rat, AngleType angletype)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -178,7 +178,7 @@ Rational RationalMath::Cos(Rational const& rat, AngleType angletype)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -198,7 +198,7 @@ Rational RationalMath::Tan(Rational const& rat, AngleType angletype)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -218,7 +218,7 @@ Rational RationalMath::ASin(Rational const& rat, AngleType angletype)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -238,7 +238,7 @@ Rational RationalMath::ACos(Rational const& rat, AngleType angletype)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -258,7 +258,7 @@ Rational RationalMath::ATan(Rational const& rat, AngleType angletype)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -278,7 +278,7 @@ Rational RationalMath::Sinh(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -298,7 +298,7 @@ Rational RationalMath::Cosh(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -318,7 +318,7 @@ Rational RationalMath::Tanh(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -338,7 +338,7 @@ Rational RationalMath::ASinh(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -358,7 +358,7 @@ Rational RationalMath::ACosh(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -378,7 +378,7 @@ Rational RationalMath::ATanh(Rational const& rat)
|
|||
catch (uint32_t error)
|
||||
{
|
||||
destroyrat(prat);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Rational result{ prat };
|
||||
|
@ -409,7 +409,7 @@ Rational RationalMath::Mod(Rational const& a, Rational const& b)
|
|||
{
|
||||
destroyrat(prat);
|
||||
destroyrat(pn);
|
||||
throw(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
auto res = Rational{ prat };
|
||||
|
|
|
@ -74,19 +74,14 @@ CCalcEngine::CCalcEngine(
|
|||
, m_bSetCalcState(false)
|
||||
, m_input(DEFAULT_DEC_SEPARATOR)
|
||||
, m_nFE(NumberFormat::Float)
|
||||
, m_maxTrigonometricNum(RationalMath::Pow(10, 100))
|
||||
, m_memoryValue{ make_unique<Rational>() }
|
||||
, m_holdVal{}
|
||||
, m_currentVal{}
|
||||
, m_lastVal{}
|
||||
, m_parenVals{}
|
||||
, m_precedenceVals{}
|
||||
, m_bError(false)
|
||||
, m_bInv(false)
|
||||
, m_bNoPrevEqu(true)
|
||||
, m_radix(DEFAULT_RADIX)
|
||||
, m_precision(DEFAULT_PRECISION)
|
||||
, m_cIntDigitsSav(DEFAULT_MAX_DIGITS)
|
||||
, m_decGrouping()
|
||||
, m_numberString(DEFAULT_NUMBER_STR)
|
||||
, m_nTempCom(0)
|
||||
, m_openParenCount(0)
|
||||
|
@ -96,15 +91,12 @@ CCalcEngine::CCalcEngine(
|
|||
, m_nLastCom(0)
|
||||
, m_angletype(AngleType::Degrees)
|
||||
, m_numwidth(NUM_WIDTH::QWORD_WIDTH)
|
||||
, m_HistoryCollector(pCalcDisplay, pHistoryDisplay, DEFAULT_DEC_SEPARATOR)
|
||||
, m_dwWordBitWidth(DwWordBitWidthFromNumWidth(m_numwidth))
|
||||
, m_HistoryCollector(pCalcDisplay, std::move(pHistoryDisplay), DEFAULT_DEC_SEPARATOR)
|
||||
, m_groupSeparator(DEFAULT_GRP_SEPARATOR)
|
||||
{
|
||||
InitChopNumbers();
|
||||
|
||||
m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(m_numwidth);
|
||||
|
||||
m_maxTrigonometricNum = RationalMath::Pow(10, 100);
|
||||
|
||||
SetRadixTypeAndNumWidth(RadixType::Decimal, m_numwidth);
|
||||
SettingsChanged();
|
||||
DisplayNum();
|
||||
|
@ -125,14 +117,14 @@ void CCalcEngine::InitChopNumbers()
|
|||
assert(m_chopNumbers.size() == m_maxDecimalValueStrings.size());
|
||||
for (size_t i = 0; i < m_chopNumbers.size(); i++)
|
||||
{
|
||||
auto maxVal = m_chopNumbers[i] / 2;
|
||||
auto maxVal = m_chopNumbers[i] >> 1;
|
||||
maxVal = RationalMath::Integer(maxVal);
|
||||
|
||||
m_maxDecimalValueStrings[i] = maxVal.ToString(10, NumberFormat::Float, m_precision);
|
||||
}
|
||||
}
|
||||
|
||||
CalcEngine::Rational CCalcEngine::GetChopNumber() const
|
||||
Rational CCalcEngine::GetChopNumber() const
|
||||
{
|
||||
return m_chopNumbers[static_cast<int>(m_numwidth)];
|
||||
}
|
||||
|
@ -170,14 +162,6 @@ void CCalcEngine::SettingsChanged()
|
|||
wstring grpStr = m_resourceProvider->GetCEngineString(L"sGrouping");
|
||||
m_decGrouping = DigitGroupingStringToGroupingVector(grpStr.empty() ? DEFAULT_GRP_STR : grpStr);
|
||||
|
||||
bool numChanged = false;
|
||||
|
||||
// if the grouping pattern or thousands symbol changed we need to refresh the display
|
||||
if (m_decGrouping != lastDecGrouping || m_groupSeparator != lastSep)
|
||||
{
|
||||
numChanged = true;
|
||||
}
|
||||
|
||||
// if the decimal symbol has changed we always do the following things
|
||||
if (m_decimalSeparator != lastDec)
|
||||
{
|
||||
|
@ -189,10 +173,10 @@ void CCalcEngine::SettingsChanged()
|
|||
s_engineStrings[SIDS_DECIMAL_SEPARATOR] = m_decimalSeparator;
|
||||
|
||||
// we need to redraw to update the decimal point button
|
||||
numChanged = true;
|
||||
DisplayNum();
|
||||
}
|
||||
|
||||
if (numChanged)
|
||||
// if the grouping pattern or thousands symbol changed we need to refresh the display
|
||||
else if (m_decGrouping != lastDecGrouping || m_groupSeparator != lastSep)
|
||||
{
|
||||
DisplayNum();
|
||||
}
|
||||
|
|
|
@ -30,17 +30,31 @@ namespace
|
|||
// 0 is returned. Higher the number, higher the precedence of the operator.
|
||||
int NPrecedenceOfOp(int nopCode)
|
||||
{
|
||||
static uint16_t rgbPrec[] = { 0, 0, IDC_OR, 0, IDC_XOR, 0, IDC_AND, 1, IDC_NAND, 1, IDC_NOR, 1, IDC_ADD, 2, IDC_SUB, 2, IDC_RSHF, 3,
|
||||
IDC_LSHF, 3, IDC_RSHFL, 3, IDC_MOD, 3, IDC_DIV, 3, IDC_MUL, 3, IDC_PWR, 4, IDC_ROOT, 4, IDC_LOGBASEY, 4 };
|
||||
|
||||
for (unsigned int iPrec = 0; iPrec < size(rgbPrec); iPrec += 2)
|
||||
switch (nopCode)
|
||||
{
|
||||
if (nopCode == rgbPrec[iPrec])
|
||||
{
|
||||
return rgbPrec[iPrec + 1];
|
||||
}
|
||||
}
|
||||
default:
|
||||
case IDC_OR:
|
||||
case IDC_XOR:
|
||||
return 0;
|
||||
case IDC_AND:
|
||||
case IDC_NAND:
|
||||
case IDC_NOR:
|
||||
return 1;
|
||||
case IDC_ADD:
|
||||
case IDC_SUB:
|
||||
return 2;
|
||||
case IDC_LSHF:
|
||||
case IDC_RSHF:
|
||||
case IDC_RSHFL:
|
||||
case IDC_MOD:
|
||||
case IDC_DIV:
|
||||
case IDC_MUL:
|
||||
return 3;
|
||||
case IDC_PWR:
|
||||
case IDC_ROOT:
|
||||
case IDC_LOGBASEY:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,9 +71,9 @@ void CCalcEngine::HandleErrorCommand(OpCode idc)
|
|||
}
|
||||
}
|
||||
|
||||
void CCalcEngine::HandleMaxDigitsReached()
|
||||
void CCalcEngine::HandleMaxDigitsReached() const
|
||||
{
|
||||
if (nullptr != m_pCalcDisplay)
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
{
|
||||
m_pCalcDisplay->MaxDigitsReached();
|
||||
}
|
||||
|
@ -75,9 +89,9 @@ void CCalcEngine::ClearTemporaryValues()
|
|||
m_bError = false;
|
||||
}
|
||||
|
||||
void CCalcEngine::ClearDisplay()
|
||||
void CCalcEngine::ClearDisplay() const
|
||||
{
|
||||
if (nullptr != m_pCalcDisplay)
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
{
|
||||
m_pCalcDisplay->SetExpressionDisplay(make_shared<vector<pair<wstring, int>>>(), make_shared<vector<shared_ptr<IExpressionCommand>>>());
|
||||
}
|
||||
|
@ -105,7 +119,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
if (!IsGuiSettingOpCode(wParam))
|
||||
{
|
||||
m_nLastCom = m_nTempCom;
|
||||
m_nTempCom = (int)wParam;
|
||||
m_nTempCom = static_cast<int>(wParam);
|
||||
}
|
||||
|
||||
// Clear expression shown after = sign, when user do any action.
|
||||
|
@ -137,8 +151,8 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
{
|
||||
if (IsBinOpCode(wParam) || IsUnaryOpCode(wParam) || IsOpInRange(wParam, IDC_FE, IDC_MMINUS) || IsOpInRange(wParam, IDC_OPENP, IDC_CLOSEP)
|
||||
|| IsOpInRange(wParam, IDM_HEX, IDM_BIN) || IsOpInRange(wParam, IDM_QWORD, IDM_BYTE) || IsOpInRange(wParam, IDM_DEG, IDM_GRAD)
|
||||
|| IsOpInRange(wParam, IDC_BINEDITSTART, IDC_BINEDITEND) || (IDC_INV == wParam) || (IDC_SIGN == wParam && 10 != m_radix) || (IDC_RAND == wParam)
|
||||
|| (IDC_EULER == wParam))
|
||||
|| IsOpInRange(wParam, IDC_BINEDITSTART, IDC_BINEDITEND) || IDC_INV == wParam || IDC_SIGN == wParam && 10 != m_radix || IDC_RAND == wParam
|
||||
|| IDC_EULER == wParam)
|
||||
{
|
||||
m_bRecord = false;
|
||||
m_currentVal = m_input.ToRational(m_radix, m_precision);
|
||||
|
@ -158,7 +172,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
unsigned int iValue = static_cast<unsigned int>(wParam - IDC_0);
|
||||
|
||||
// this is redundant, illegal keys are disabled
|
||||
if (iValue >= static_cast<unsigned int>(m_radix))
|
||||
if (iValue >= m_radix)
|
||||
{
|
||||
HandleErrorCommand(wParam);
|
||||
return;
|
||||
|
@ -184,7 +198,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
{
|
||||
bool fPrecInvToHigher = false; // Is Precedence Inversion from lower to higher precedence happening ??
|
||||
|
||||
m_nOpCode = (int)wParam;
|
||||
m_nOpCode = static_cast<int>(wParam);
|
||||
|
||||
// Check to see if by changing this binop, a Precedence inversion is happening.
|
||||
// Eg. 1 * 2 + and + is getting changed to ^. The previous precedence rules would have already computed
|
||||
|
@ -221,10 +235,10 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
{
|
||||
DoPrecedenceCheckAgain:
|
||||
|
||||
int nx = NPrecedenceOfOp((int)wParam);
|
||||
int nx = NPrecedenceOfOp(static_cast<int>(wParam));
|
||||
int ni = NPrecedenceOfOp(m_nOpCode);
|
||||
|
||||
if ((nx > ni) && m_fPrecedence)
|
||||
if (nx > ni && m_fPrecedence)
|
||||
{
|
||||
if (m_precedenceOpCount < MAXPRECDEPTH)
|
||||
{
|
||||
|
@ -260,10 +274,9 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
}
|
||||
}
|
||||
|
||||
if ((m_precedenceOpCount != 0) && (m_nPrecOp[m_precedenceOpCount - 1]))
|
||||
if (m_precedenceOpCount != 0 && m_nPrecOp[m_precedenceOpCount - 1])
|
||||
{
|
||||
m_precedenceOpCount--;
|
||||
m_nOpCode = m_nPrecOp[m_precedenceOpCount];
|
||||
m_nOpCode = m_nPrecOp[--m_precedenceOpCount];
|
||||
|
||||
m_lastVal = m_precedenceVals[m_precedenceOpCount];
|
||||
|
||||
|
@ -285,14 +298,14 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
|
||||
DisplayAnnounceBinaryOperator();
|
||||
m_lastVal = m_currentVal;
|
||||
m_nOpCode = (int)wParam;
|
||||
m_nOpCode = static_cast<int>(wParam);
|
||||
m_HistoryCollector.AddBinOpToHistory(m_nOpCode, m_fIntegerMode);
|
||||
m_bNoPrevEqu = m_bChangeOp = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// UNARY OPERATORS:
|
||||
if (IsUnaryOpCode(wParam) || (wParam == IDC_DEGREES))
|
||||
if (IsUnaryOpCode(wParam) || wParam == IDC_DEGREES)
|
||||
{
|
||||
/* Functions are unary operations. */
|
||||
/* If the last thing done was an operator, m_currentVal was cleared. */
|
||||
|
@ -313,11 +326,11 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal);
|
||||
}
|
||||
|
||||
m_HistoryCollector.AddUnaryOpToHistory((int)wParam, m_bInv, m_angletype);
|
||||
m_HistoryCollector.AddUnaryOpToHistory(static_cast<int>(wParam), m_bInv, m_angletype);
|
||||
}
|
||||
|
||||
if ((wParam == IDC_SIN) || (wParam == IDC_COS) || (wParam == IDC_TAN) || (wParam == IDC_SINH) || (wParam == IDC_COSH) || (wParam == IDC_TANH)
|
||||
|| (wParam == IDC_SEC) || (wParam == IDC_CSC) || (wParam == IDC_COT) || (wParam == IDC_SECH) || (wParam == IDC_CSCH) || (wParam == IDC_COTH))
|
||||
if (wParam == IDC_SIN || wParam == IDC_COS || wParam == IDC_TAN || wParam == IDC_SINH || wParam == IDC_COSH || wParam == IDC_TANH
|
||||
|| wParam == IDC_SEC || wParam == IDC_CSC || wParam == IDC_COT || wParam == IDC_SECH || wParam == IDC_CSCH || wParam == IDC_COTH)
|
||||
{
|
||||
if (IsCurrentTooBigForTrig())
|
||||
{
|
||||
|
@ -327,7 +340,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
}
|
||||
}
|
||||
|
||||
m_currentVal = SciCalcFunctions(m_currentVal, (uint32_t)wParam);
|
||||
m_currentVal = SciCalcFunctions(m_currentVal, static_cast<uint32_t>(wParam));
|
||||
|
||||
if (m_bError)
|
||||
return;
|
||||
|
@ -345,9 +358,9 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
and have been used */
|
||||
|
||||
if (m_bInv
|
||||
&& ((wParam == IDC_CHOP) || (wParam == IDC_SIN) || (wParam == IDC_COS) || (wParam == IDC_TAN) || (wParam == IDC_LN) || (wParam == IDC_DMS)
|
||||
|| (wParam == IDC_DEGREES) || (wParam == IDC_SINH) || (wParam == IDC_COSH) || (wParam == IDC_TANH) || (wParam == IDC_SEC) || (wParam == IDC_CSC)
|
||||
|| (wParam == IDC_COT) || (wParam == IDC_SECH) || (wParam == IDC_CSCH) || (wParam == IDC_COTH)))
|
||||
&& (wParam == IDC_CHOP || wParam == IDC_SIN || wParam == IDC_COS || wParam == IDC_TAN || wParam == IDC_LN || wParam == IDC_DMS
|
||||
|| wParam == IDC_DEGREES || wParam == IDC_SINH || wParam == IDC_COSH || wParam == IDC_TANH || wParam == IDC_SEC || wParam == IDC_CSC
|
||||
|| wParam == IDC_COT || wParam == IDC_SECH || wParam == IDC_CSCH || wParam == IDC_COTH))
|
||||
{
|
||||
m_bInv = false;
|
||||
}
|
||||
|
@ -366,7 +379,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
|
||||
CheckAndAddLastBinOpToHistory();
|
||||
|
||||
if (TryToggleBit(m_currentVal, (uint32_t)wParam - IDC_BINEDITSTART))
|
||||
if (TryToggleBit(m_currentVal, static_cast<uint32_t>(wParam) - IDC_BINEDITSTART))
|
||||
{
|
||||
DisplayNum();
|
||||
}
|
||||
|
@ -396,7 +409,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
|
||||
/* clear the parenthesis status box indicator, this will not be
|
||||
cleared for CENTR */
|
||||
if (nullptr != m_pCalcDisplay)
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
{
|
||||
m_pCalcDisplay->SetParenthesisNumber(0);
|
||||
ClearDisplay();
|
||||
|
@ -443,7 +456,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
m_nTempCom = m_nLastCom; // Put back this last saved command to the prev state so ) can be handled properly
|
||||
ProcessCommand(IDC_CLOSEP);
|
||||
m_nLastCom = m_nTempCom; // Actually this is IDC_CLOSEP
|
||||
m_nTempCom = (int)wParam; // put back in the state where last op seen was IDC_CLOSEP, and current op is IDC_EQU
|
||||
m_nTempCom = static_cast<int>(wParam); // put back in the state where last op seen was IDC_CLOSEP, and current op is IDC_EQU
|
||||
}
|
||||
|
||||
if (!m_bNoPrevEqu)
|
||||
|
@ -473,8 +486,8 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
m_lastVal = m_precedenceVals[m_precedenceOpCount];
|
||||
|
||||
// Precedence Inversion check
|
||||
int ni = NPrecedenceOfOp(m_nPrevOpCode);
|
||||
int nx = NPrecedenceOfOp(m_nOpCode);
|
||||
auto ni = NPrecedenceOfOp(m_nPrevOpCode);
|
||||
auto nx = NPrecedenceOfOp(m_nOpCode);
|
||||
if (ni <= nx)
|
||||
{
|
||||
m_HistoryCollector.EnclosePrecInversionBrackets();
|
||||
|
@ -488,8 +501,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
|
||||
if (!m_bError)
|
||||
{
|
||||
wstring groupedString = GroupDigitsPerRadix(m_numberString, m_radix);
|
||||
m_HistoryCollector.CompleteEquation(groupedString);
|
||||
m_HistoryCollector.CompleteEquation(GroupDigitsPerRadix(m_numberString, m_radix));
|
||||
}
|
||||
|
||||
m_bChangeOp = false;
|
||||
|
@ -504,10 +516,10 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
// -OR- the paren holding array is empty and we try to remove a
|
||||
// paren
|
||||
// -OR- the precedence holding array is full
|
||||
if ((m_openParenCount >= MAXPRECDEPTH && (wParam == IDC_OPENP)) || (!m_openParenCount && (wParam != IDC_OPENP))
|
||||
|| ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0)))
|
||||
if (m_openParenCount >= MAXPRECDEPTH && wParam == IDC_OPENP || !m_openParenCount && wParam != IDC_OPENP
|
||||
|| m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0)
|
||||
{
|
||||
if (!m_openParenCount && (wParam != IDC_OPENP))
|
||||
if (!m_openParenCount && wParam != IDC_OPENP)
|
||||
{
|
||||
m_pCalcDisplay->OnNoRightParenAdded();
|
||||
}
|
||||
|
@ -530,7 +542,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
// Open level of parentheses, save number and operation.
|
||||
m_parenVals[m_openParenCount] = m_lastVal;
|
||||
|
||||
m_nOp[m_openParenCount++] = (m_bChangeOp ? m_nOpCode : 0);
|
||||
m_nOp[m_openParenCount++] = m_bChangeOp ? m_nOpCode : 0;
|
||||
|
||||
/* save a special marker on the precedence array */
|
||||
if (m_precedenceOpCount < m_nPrecOp.size())
|
||||
|
@ -567,7 +579,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
m_nPrevOpCode = m_nOpCode;
|
||||
|
||||
// Now process the precedence stack till we get to an opcode which is zero.
|
||||
for (m_nOpCode = m_nPrecOp[--m_precedenceOpCount]; m_nOpCode; m_nOpCode = m_nPrecOp[--m_precedenceOpCount])
|
||||
for (m_nOpCode = m_nPrecOp[--m_precedenceOpCount]; m_nOpCode != 0; m_nOpCode = m_nPrecOp[--m_precedenceOpCount])
|
||||
{
|
||||
// Precedence Inversion check
|
||||
int ni = NPrecedenceOfOp(m_nPrevOpCode);
|
||||
|
@ -587,17 +599,15 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
m_HistoryCollector.AddCloseBraceToHistory();
|
||||
|
||||
// Now get back the operation and opcode at the beginning of this parenthesis pair
|
||||
|
||||
m_openParenCount -= 1;
|
||||
m_lastVal = m_parenVals[m_openParenCount];
|
||||
m_lastVal = m_parenVals[--m_openParenCount];
|
||||
m_nOpCode = m_nOp[m_openParenCount];
|
||||
|
||||
// m_bChangeOp should be true if m_nOpCode is valid
|
||||
m_bChangeOp = (m_nOpCode != 0);
|
||||
m_bChangeOp = m_nOpCode != 0;
|
||||
}
|
||||
|
||||
// Set the "(=xx" indicator.
|
||||
if (nullptr != m_pCalcDisplay)
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
{
|
||||
m_pCalcDisplay->SetParenthesisNumber(static_cast<unsigned int>(m_openParenCount));
|
||||
}
|
||||
|
@ -615,7 +625,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
case IDM_OCT:
|
||||
case IDM_BIN:
|
||||
{
|
||||
SetRadixTypeAndNumWidth((RadixType)(wParam - IDM_HEX), (NUM_WIDTH)-1);
|
||||
SetRadixTypeAndNumWidth(static_cast<RadixType>(wParam - IDM_HEX), static_cast<NUM_WIDTH>(-1));
|
||||
m_HistoryCollector.UpdateHistoryExpression(m_radix, m_precision);
|
||||
break;
|
||||
}
|
||||
|
@ -631,7 +641,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
}
|
||||
|
||||
// Compat. mode BaseX: Qword, Dword, Word, Byte
|
||||
SetRadixTypeAndNumWidth((RadixType)-1, (NUM_WIDTH)(wParam - IDM_QWORD));
|
||||
SetRadixTypeAndNumWidth(static_cast<RadixType>(-1), static_cast<NUM_WIDTH>(wParam - IDM_QWORD));
|
||||
break;
|
||||
|
||||
case IDM_DEG:
|
||||
|
@ -666,7 +676,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal);
|
||||
}
|
||||
|
||||
m_currentVal = -(m_currentVal);
|
||||
m_currentVal = -m_currentVal;
|
||||
|
||||
DisplayNum();
|
||||
m_HistoryCollector.AddUnaryOpToHistory(IDC_SIGN, m_bInv, m_angletype);
|
||||
|
@ -731,7 +741,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
wstringstream str;
|
||||
str << fixed << setprecision(m_precision) << GenerateRandomNumber();
|
||||
|
||||
auto rat = StringToRat(false, str.str(), false, L"", m_radix, m_precision);
|
||||
auto* rat = StringToRat(false, str.str(), false, L"", m_radix, m_precision);
|
||||
if (rat != nullptr)
|
||||
{
|
||||
m_currentVal = Rational{ rat };
|
||||
|
@ -762,7 +772,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
break;
|
||||
case IDC_FE:
|
||||
// Toggle exponential notation display.
|
||||
m_nFE = NumberFormat(!(int)m_nFE);
|
||||
m_nFE = m_nFE == NumberFormat::Float ? NumberFormat::Scientific : NumberFormat::Float;
|
||||
DisplayNum();
|
||||
break;
|
||||
|
||||
|
@ -842,9 +852,13 @@ void CCalcEngine::ResolveHighestPrecedenceOperation()
|
|||
// If you are messing with this, test cases like this CE, statistical functions, ( & MR buttons
|
||||
void CCalcEngine::CheckAndAddLastBinOpToHistory(bool addToHistory)
|
||||
{
|
||||
if (m_bChangeOp)
|
||||
// Cannot do anything if this is not added to history
|
||||
if (!m_HistoryCollector.FOpndAddedToHistory())
|
||||
{
|
||||
if (m_HistoryCollector.FOpndAddedToHistory())
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_bChangeOp)
|
||||
{
|
||||
// if last time opnd was added but the last command was not a binary operator, then it must have come
|
||||
// from commands which add the operand, like unary operator. So history at this is showing 1 + sqrt(4)
|
||||
|
@ -852,15 +866,14 @@ void CCalcEngine::CheckAndAddLastBinOpToHistory(bool addToHistory)
|
|||
// So erase the last operand
|
||||
m_HistoryCollector.RemoveLastOpndFromHistory();
|
||||
}
|
||||
}
|
||||
else if (m_HistoryCollector.FOpndAddedToHistory() && !m_bError)
|
||||
else if (!m_bError)
|
||||
{
|
||||
// Corner case, where opnd is already in history but still a new opnd starting (1 + 4 sqrt 5). This is yet another
|
||||
// special casing of previous case under if (m_bChangeOp), but this time we can do better than just removing it
|
||||
// Let us make a current value =. So in case of 4 SQRT (or a equation under braces) and then a new equation is started, we can just form
|
||||
// a useful equation of sqrt(4) = 2 and continue a new equation from now on. But no point in doing this for things like
|
||||
// MR, SUM etc. All you will get is 5 = 5 kind of no useful equation.
|
||||
if ((IsUnaryOpCode(m_nLastCom) || IDC_SIGN == m_nLastCom || IDC_CLOSEP == m_nLastCom) && 0 == m_openParenCount)
|
||||
if ((IsUnaryOpCode(m_nLastCom) || m_nLastCom == IDC_SIGN || m_nLastCom == IDC_CLOSEP) && m_openParenCount == 0)
|
||||
{
|
||||
if (addToHistory)
|
||||
{
|
||||
|
@ -876,23 +889,27 @@ void CCalcEngine::CheckAndAddLastBinOpToHistory(bool addToHistory)
|
|||
|
||||
// change the display area from a static text to an editbox, which has the focus can make
|
||||
// Magnifier (Accessibility tool) work
|
||||
void CCalcEngine::SetPrimaryDisplay(const wstring& szText, bool isError)
|
||||
void CCalcEngine::SetPrimaryDisplay(const wstring& szText, bool isError) const
|
||||
{
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
if (m_pCalcDisplay == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_pCalcDisplay->SetPrimaryDisplay(szText, isError);
|
||||
m_pCalcDisplay->SetIsInError(isError);
|
||||
}
|
||||
}
|
||||
|
||||
void CCalcEngine::DisplayAnnounceBinaryOperator()
|
||||
void CCalcEngine::DisplayAnnounceBinaryOperator() const
|
||||
{
|
||||
// If m_pCalcDisplay is null, this is not a high priority function
|
||||
// and should not be the reason we crash.
|
||||
if (m_pCalcDisplay != nullptr)
|
||||
if (m_pCalcDisplay == nullptr)
|
||||
{
|
||||
m_pCalcDisplay->BinaryOperatorReceived();
|
||||
return;
|
||||
}
|
||||
|
||||
m_pCalcDisplay->BinaryOperatorReceived();
|
||||
}
|
||||
|
||||
// Unary operator Function Name table Element
|
||||
|
@ -911,7 +928,7 @@ struct FunctionNameElement
|
|||
|
||||
wstring programmerModeString;
|
||||
|
||||
bool hasAngleStrings = ((!radString.empty()) || (!inverseRadString.empty()) || (!gradString.empty()) || (!inverseGradString.empty()));
|
||||
bool hasAngleStrings = !radString.empty() || !inverseRadString.empty() || !gradString.empty() || !inverseGradString.empty();
|
||||
};
|
||||
|
||||
// Table for each unary operator
|
||||
|
@ -959,9 +976,9 @@ static const std::unordered_map<int, FunctionNameElement> operatorStringTable =
|
|||
wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, AngleType angletype)
|
||||
{
|
||||
// Try to lookup the ID in the UFNE table
|
||||
wstring ids = L"";
|
||||
wstring ids;
|
||||
|
||||
if (auto pair = operatorStringTable.find(nOpCode); pair != operatorStringTable.end())
|
||||
if (const auto pair = operatorStringTable.find(nOpCode); pair != operatorStringTable.end())
|
||||
{
|
||||
const FunctionNameElement& element = pair->second;
|
||||
if (!element.hasAngleStrings || AngleType::Degrees == angletype)
|
||||
|
@ -1000,21 +1017,21 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, AngleType
|
|||
}
|
||||
}
|
||||
|
||||
if (!ids.empty())
|
||||
if (ids.empty())
|
||||
{
|
||||
return GetString(ids);
|
||||
}
|
||||
|
||||
// If we didn't find an ID in the table, use the op code.
|
||||
return OpCodeToString(nOpCode);
|
||||
}
|
||||
|
||||
return GetString(ids);
|
||||
}
|
||||
|
||||
wstring_view CCalcEngine::OpCodeToBinaryString(int nOpCode, bool isIntegerMode)
|
||||
{
|
||||
// Try to lookup the ID in the UFNE table
|
||||
wstring ids = L"";
|
||||
wstring ids;
|
||||
|
||||
if (auto pair = operatorStringTable.find(nOpCode); pair != operatorStringTable.end())
|
||||
if (const auto pair = operatorStringTable.find(nOpCode); pair != operatorStringTable.end())
|
||||
{
|
||||
if (isIntegerMode && !pair->second.programmerModeString.empty())
|
||||
{
|
||||
|
@ -1026,28 +1043,28 @@ wstring_view CCalcEngine::OpCodeToBinaryString(int nOpCode, bool isIntegerMode)
|
|||
}
|
||||
}
|
||||
|
||||
if (!ids.empty())
|
||||
if (ids.empty())
|
||||
{
|
||||
return GetString(ids);
|
||||
}
|
||||
|
||||
// If we didn't find an ID in the table, use the op code.
|
||||
return OpCodeToString(nOpCode);
|
||||
}
|
||||
|
||||
return GetString(ids);
|
||||
}
|
||||
|
||||
bool CCalcEngine::IsCurrentTooBigForTrig()
|
||||
bool CCalcEngine::IsCurrentTooBigForTrig() const
|
||||
{
|
||||
return m_currentVal >= m_maxTrigonometricNum;
|
||||
}
|
||||
|
||||
uint32_t CCalcEngine::GetCurrentRadix()
|
||||
uint32_t CCalcEngine::GetCurrentRadix() const
|
||||
{
|
||||
return m_radix;
|
||||
}
|
||||
|
||||
wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix)
|
||||
{
|
||||
Rational rat = (m_bRecord ? m_input.ToRational(m_radix, m_precision) : m_currentVal);
|
||||
const Rational rat = m_bRecord ? m_input.ToRational(m_radix, m_precision) : m_currentVal;
|
||||
|
||||
ChangeConstants(m_radix, precision);
|
||||
|
||||
|
@ -1068,7 +1085,7 @@ wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision,
|
|||
}
|
||||
}
|
||||
|
||||
wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix)
|
||||
wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix) const
|
||||
{
|
||||
wstring result{};
|
||||
// Check for standard\scientific mode
|
||||
|
@ -1084,9 +1101,7 @@ wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix)
|
|||
|
||||
try
|
||||
{
|
||||
uint64_t w64Bits = tempRat.ToUInt64_t();
|
||||
bool fMsb = ((w64Bits >> (m_dwWordBitWidth - 1)) & 1);
|
||||
if ((radix == 10) && fMsb)
|
||||
if (radix == 10 && ((tempRat.ToUInt64_t() & (1ULL << (m_dwWordBitWidth - 1))) != 0))
|
||||
{
|
||||
// If high bit is set, then get the decimal number in negative 2's complement form.
|
||||
tempRat = -((tempRat ^ GetChopNumber()) + 1);
|
||||
|
@ -1110,5 +1125,5 @@ double CCalcEngine::GenerateRandomNumber()
|
|||
m_randomGeneratorEngine = std::make_unique<std::mt19937>(rd());
|
||||
m_distr = std::make_unique<std::uniform_real_distribution<>>(0, 1);
|
||||
}
|
||||
return (*m_distr.get())(*m_randomGeneratorEngine.get());
|
||||
return (*m_distr)(*m_randomGeneratorEngine);
|
||||
}
|
||||
|
|
|
@ -48,10 +48,10 @@ typedef struct
|
|||
bool bUseSep;
|
||||
} LASTDISP;
|
||||
|
||||
static LASTDISP gldPrevious = { 0, -1, 0, -1, (NUM_WIDTH)-1, false, false, false };
|
||||
static LASTDISP gldPrevious = { 0, -1, 0, -1, static_cast<NUM_WIDTH>(-1), false, false, false };
|
||||
|
||||
// Truncates if too big, makes it a non negative - the number in rat. Doesn't do anything if not in INT mode
|
||||
CalcEngine::Rational CCalcEngine::TruncateNumForIntMath(CalcEngine::Rational const& rat)
|
||||
CalcEngine::Rational CCalcEngine::TruncateNumForIntMath(CalcEngine::Rational const& rat) const
|
||||
{
|
||||
if (!m_fIntegerMode)
|
||||
{
|
||||
|
@ -60,22 +60,23 @@ CalcEngine::Rational CCalcEngine::TruncateNumForIntMath(CalcEngine::Rational con
|
|||
|
||||
// Truncate to an integer. Do not round here.
|
||||
auto result = RationalMath::Integer(rat);
|
||||
const auto chopNumber = GetChopNumber();
|
||||
|
||||
// Can be converting a dec negative number to Hex/Oct/Bin rep. Use 2's complement form
|
||||
// Check the range.
|
||||
if (result < 0)
|
||||
{
|
||||
// if negative make positive by doing a twos complement
|
||||
result = -(result)-1;
|
||||
result ^= GetChopNumber();
|
||||
result = -result-1;
|
||||
result ^= chopNumber;
|
||||
}
|
||||
|
||||
result &= GetChopNumber();
|
||||
result &= chopNumber;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CCalcEngine::DisplayNum(void)
|
||||
void CCalcEngine::DisplayNum()
|
||||
{
|
||||
//
|
||||
// Only change the display if
|
||||
|
@ -84,12 +85,13 @@ void CCalcEngine::DisplayNum(void)
|
|||
// something important has changed since the last time DisplayNum was
|
||||
// called.
|
||||
//
|
||||
if (m_bRecord || gldPrevious.value != m_currentVal || gldPrevious.precision != m_precision || gldPrevious.radix != m_radix || gldPrevious.nFE != (int)m_nFE
|
||||
|| !gldPrevious.bUseSep || gldPrevious.numwidth != m_numwidth || gldPrevious.fIntMath != m_fIntegerMode || gldPrevious.bRecord != m_bRecord)
|
||||
if (m_bRecord || gldPrevious.value != m_currentVal || gldPrevious.precision != m_precision || gldPrevious.radix != m_radix
|
||||
|| gldPrevious.nFE != static_cast<int>(m_nFE) || !gldPrevious.bUseSep || gldPrevious.numwidth != m_numwidth || gldPrevious.fIntMath != m_fIntegerMode
|
||||
|| gldPrevious.bRecord != m_bRecord)
|
||||
{
|
||||
gldPrevious.precision = m_precision;
|
||||
gldPrevious.radix = m_radix;
|
||||
gldPrevious.nFE = (int)m_nFE;
|
||||
gldPrevious.nFE = static_cast<int>(m_nFE);
|
||||
gldPrevious.numwidth = m_numwidth;
|
||||
|
||||
gldPrevious.fIntMath = m_fIntegerMode;
|
||||
|
@ -114,7 +116,7 @@ void CCalcEngine::DisplayNum(void)
|
|||
// Displayed number can go through transformation. So copy it after transformation
|
||||
gldPrevious.value = m_currentVal;
|
||||
|
||||
if ((m_radix == 10) && IsNumberInvalid(m_numberString, MAX_EXPONENT, m_precision, m_radix))
|
||||
if (m_radix == 10 && (IsNumberInvalid(m_numberString, MAX_EXPONENT, m_precision, m_radix) != 0))
|
||||
{
|
||||
DisplayError(CALC_E_OVERFLOW);
|
||||
}
|
||||
|
@ -156,7 +158,7 @@ int CCalcEngine::IsNumberInvalid(const wstring& numberString, int iMaxExp, int i
|
|||
auto intEnd = exp.end();
|
||||
while (intItr != intEnd && *intItr == L'0')
|
||||
{
|
||||
intItr++;
|
||||
++intItr;
|
||||
}
|
||||
|
||||
auto iMantissa = distance(intItr, intEnd) + matches.length(2);
|
||||
|
@ -177,7 +179,7 @@ int CCalcEngine::IsNumberInvalid(const wstring& numberString, int iMaxExp, int i
|
|||
{
|
||||
if (radix == 16)
|
||||
{
|
||||
if (!(iswdigit(c) || (c >= L'A' && c <= L'F')))
|
||||
if (!(iswdigit(c) || c >= L'A' && c <= L'F'))
|
||||
{
|
||||
iError = IDS_ERR_UNK_CH;
|
||||
}
|
||||
|
@ -234,7 +236,7 @@ vector<uint32_t> CCalcEngine::DigitGroupingStringToGroupingVector(wstring_view g
|
|||
// If we found a grouping and aren't at the end of the string yet,
|
||||
// jump to the next position in the string (the ';').
|
||||
// The loop will then increment us to the next character, which should be a number.
|
||||
if (next && (static_cast<size_t>(next - begin) < groupingString.length()))
|
||||
if (next && static_cast<size_t>(next - begin) < groupingString.length())
|
||||
{
|
||||
itr = next;
|
||||
}
|
||||
|
@ -243,7 +245,7 @@ vector<uint32_t> CCalcEngine::DigitGroupingStringToGroupingVector(wstring_view g
|
|||
return grouping;
|
||||
}
|
||||
|
||||
wstring CCalcEngine::GroupDigitsPerRadix(wstring_view numberString, uint32_t radix)
|
||||
wstring CCalcEngine::GroupDigitsPerRadix(wstring_view numberString, uint32_t radix) const
|
||||
{
|
||||
if (numberString.empty())
|
||||
{
|
||||
|
@ -253,7 +255,7 @@ wstring CCalcEngine::GroupDigitsPerRadix(wstring_view numberString, uint32_t rad
|
|||
switch (radix)
|
||||
{
|
||||
case 10:
|
||||
return GroupDigits(wstring{ m_groupSeparator }, m_decGrouping, numberString, (L'-' == numberString[0]));
|
||||
return GroupDigits(wstring{ m_groupSeparator }, m_decGrouping, numberString, L'-' == numberString[0]);
|
||||
case 8:
|
||||
return GroupDigits(L" ", { 3, 0 }, numberString);
|
||||
case 2:
|
||||
|
@ -283,7 +285,7 @@ wstring CCalcEngine::GroupDigitsPerRadix(wstring_view numberString, uint32_t rad
|
|||
* 5,3,2 - group 5, then 3, then 2, then no grouping after
|
||||
*
|
||||
\***************************************************************************/
|
||||
wstring CCalcEngine::GroupDigits(wstring_view delimiter, vector<uint32_t> const& grouping, wstring_view displayString, bool isNumNegative)
|
||||
wstring CCalcEngine::GroupDigits(wstring_view delimiter, vector<uint32_t> const& grouping, wstring_view displayString, bool isNumNegative) const
|
||||
{
|
||||
// if there's nothing to do, bail
|
||||
if (delimiter.empty() || grouping.empty())
|
||||
|
@ -293,11 +295,11 @@ wstring CCalcEngine::GroupDigits(wstring_view delimiter, vector<uint32_t> const&
|
|||
|
||||
// Find the position of exponential 'e' in the string
|
||||
size_t exp = displayString.find(L'e');
|
||||
bool hasExponent = (exp != wstring_view::npos);
|
||||
bool hasExponent = exp != wstring_view::npos;
|
||||
|
||||
// Find the position of decimal point in the string
|
||||
size_t dec = displayString.find(m_decimalSeparator);
|
||||
bool hasDecimal = (dec != wstring_view::npos);
|
||||
bool hasDecimal = dec != wstring_view::npos;
|
||||
|
||||
// Create an iterator that points to the end of the portion of the number subject to grouping (i.e. left of the decimal)
|
||||
auto ritr = displayString.rend();
|
||||
|
@ -332,7 +334,7 @@ wstring CCalcEngine::GroupDigits(wstring_view delimiter, vector<uint32_t> const&
|
|||
// Do not add a separator if:
|
||||
// - grouping size is 0
|
||||
// - we are at the end of the digit string
|
||||
if (currGrouping != 0 && (groupingSize % currGrouping) == 0 && ritr != reverse_end)
|
||||
if (currGrouping != 0 && groupingSize % currGrouping == 0 && ritr != reverse_end)
|
||||
{
|
||||
result += delimiter;
|
||||
groupingSize = 0; // reset for a new group
|
||||
|
@ -340,14 +342,13 @@ wstring CCalcEngine::GroupDigits(wstring_view delimiter, vector<uint32_t> const&
|
|||
// Shift the grouping to next values if they exist
|
||||
if (groupItr != grouping.end())
|
||||
{
|
||||
++groupItr;
|
||||
|
||||
// Loop through grouping vector until we find a non-zero value.
|
||||
// "0" values may appear in a form of either e.g. "3;0" or "3;0;0".
|
||||
// A 0 in the last position means repeat the previous grouping.
|
||||
// A 0 in another position is a group. So, "3;0;0" means "group 3, then group 0 repeatedly"
|
||||
// This could be expressed as just "3" but GetLocaleInfo is returning 3;0;0 in some cases instead.
|
||||
for (currGrouping = 0; groupItr != grouping.end(); ++groupItr)
|
||||
currGrouping = 0;
|
||||
while (++groupItr != grouping.end())
|
||||
{
|
||||
// If it's a non-zero value, that's our new group
|
||||
if (*groupItr != 0)
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace CalcEngine;
|
||||
using namespace CalcEngine::RationalMath;
|
||||
using namespace RationalMath;
|
||||
|
||||
/* Routines for more complex mathematical functions/error checking. */
|
||||
CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op)
|
||||
Rational CCalcEngine::SciCalcFunctions(Rational const& rat, uint32_t op)
|
||||
{
|
||||
Rational result{};
|
||||
try
|
||||
|
@ -39,7 +39,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
|
|||
case IDC_COM:
|
||||
if (m_radix == 10 && !m_fIntegerMode)
|
||||
{
|
||||
result = -(RationalMath::Integer(rat) + 1);
|
||||
result = -(Integer(rat) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -78,16 +78,16 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
|
|||
result = Integer(rat);
|
||||
|
||||
uint64_t w64Bits = result.ToUInt64_t();
|
||||
uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0;
|
||||
uint64_t lsb = w64Bits & 0x01;
|
||||
w64Bits >>= 1; // RShift by 1
|
||||
|
||||
if (op == IDC_ROR)
|
||||
{
|
||||
w64Bits |= (lsb << (m_dwWordBitWidth - 1));
|
||||
w64Bits |= lsb << (m_dwWordBitWidth - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
w64Bits |= (m_carryBit << (m_dwWordBitWidth - 1));
|
||||
w64Bits |= m_carryBit << (m_dwWordBitWidth - 1);
|
||||
m_carryBit = lsb;
|
||||
}
|
||||
|
||||
|
@ -268,11 +268,11 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
|
|||
break;
|
||||
}
|
||||
case IDC_CEIL:
|
||||
result = (Frac(rat) > 0) ? Integer(rat + 1) : Integer(rat);
|
||||
result = Frac(rat) > 0 ? Integer(rat + 1) : Integer(rat);
|
||||
break;
|
||||
|
||||
case IDC_FLOOR:
|
||||
result = (Frac(rat) < 0) ? Integer(rat - 1) : Integer(rat);
|
||||
result = Frac(rat) < 0 ? Integer(rat - 1) : Integer(rat);
|
||||
break;
|
||||
|
||||
case IDC_ABS:
|
||||
|
|
|
@ -10,7 +10,7 @@ using namespace CalcEngine::RationalMath;
|
|||
CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs)
|
||||
{
|
||||
// Remove any variance in how 0 could be represented in rat e.g. -0, 0/n, etc.
|
||||
auto result = (lhs != 0 ? lhs : 0);
|
||||
auto result = lhs != 0 ? lhs : 0;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
|
|||
break;
|
||||
|
||||
case IDC_NAND:
|
||||
result = (result & rhs) ^ GetChopNumber();
|
||||
result = result & rhs ^ GetChopNumber();
|
||||
break;
|
||||
|
||||
case IDC_NOR:
|
||||
|
@ -43,20 +43,18 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
|
|||
throw CALC_E_NORESULT;
|
||||
}
|
||||
|
||||
uint64_t w64Bits = rhs.ToUInt64_t();
|
||||
bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
|
||||
|
||||
Rational holdVal = result;
|
||||
result = rhs >> holdVal;
|
||||
|
||||
if (fMsb)
|
||||
if ((rhs.ToUInt64_t() & (1ULL << (m_dwWordBitWidth - 1))) != 0)
|
||||
{
|
||||
result = Integer(result);
|
||||
const auto chopNumber = GetChopNumber();
|
||||
|
||||
auto tempRat = GetChopNumber() >> holdVal;
|
||||
auto tempRat = chopNumber >> holdVal;
|
||||
tempRat = Integer(tempRat);
|
||||
|
||||
result |= tempRat ^ GetChopNumber();
|
||||
result |= tempRat ^ chopNumber;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -94,51 +92,47 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
|
|||
case IDC_DIV:
|
||||
case IDC_MOD:
|
||||
{
|
||||
int iNumeratorSign = 1, iDenominatorSign = 1;
|
||||
bool isNumeratorNegative = false, isDenominatorNegative = false;
|
||||
auto temp = result;
|
||||
result = rhs;
|
||||
|
||||
if (m_fIntegerMode)
|
||||
{
|
||||
uint64_t w64Bits = rhs.ToUInt64_t();
|
||||
bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
|
||||
|
||||
if (fMsb)
|
||||
const uint64_t mask = 1ULL << (m_dwWordBitWidth - 1);
|
||||
if ((w64Bits & mask) != 0)
|
||||
{
|
||||
result = (rhs ^ GetChopNumber()) + 1;
|
||||
|
||||
iNumeratorSign = -1;
|
||||
isNumeratorNegative = true;
|
||||
}
|
||||
|
||||
w64Bits = temp.ToUInt64_t();
|
||||
fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
|
||||
|
||||
if (fMsb)
|
||||
if ((w64Bits & mask) != 0)
|
||||
{
|
||||
temp = (temp ^ GetChopNumber()) + 1;
|
||||
|
||||
iDenominatorSign = -1;
|
||||
isDenominatorNegative = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (operation == IDC_DIV)
|
||||
{
|
||||
result /= temp;
|
||||
if (m_fIntegerMode && (iNumeratorSign * iDenominatorSign) == -1)
|
||||
if (m_fIntegerMode && isNumeratorNegative != isDenominatorNegative)
|
||||
{
|
||||
result = -(Integer(result));
|
||||
result = -Integer(result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_fIntegerMode)
|
||||
else if (m_fIntegerMode)
|
||||
{
|
||||
// Programmer mode, use remrat (remainder after division)
|
||||
result %= temp;
|
||||
|
||||
if (iNumeratorSign == -1)
|
||||
if (isNumeratorNegative)
|
||||
{
|
||||
result = -(Integer(result));
|
||||
result = -Integer(result);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -146,7 +140,7 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
|
|||
// other modes, use modrat (modulus after division)
|
||||
result = Mod(result, temp);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -159,7 +153,7 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
|
|||
break;
|
||||
|
||||
case IDC_LOGBASEY:
|
||||
result = (Log(rhs) / Log(result));
|
||||
result = Log(rhs) / Log(result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,18 +16,11 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidt
|
|||
// convert to 2's complement form, but this time all high bits will be propagated. Eg. -127, in byte mode is
|
||||
// represented as 1000,0001. This puts it back as sign=-1, 01111111 . But DisplayNum will see this and convert it
|
||||
// back to 1111,1111,1000,0001 when in Word mode.
|
||||
if (m_fIntegerMode)
|
||||
{
|
||||
uint64_t w64Bits = m_currentVal.ToUInt64_t();
|
||||
bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; // make sure you use the old width
|
||||
|
||||
if (fMsb)
|
||||
if (m_fIntegerMode && (m_currentVal.ToUInt64_t() & (1ULL << (m_dwWordBitWidth - 1))) != 0)
|
||||
{
|
||||
// make sure you use the old width
|
||||
// If high bit is set, then get the decimal number in -ve 2'scompl form.
|
||||
auto tempResult = m_currentVal ^ GetChopNumber();
|
||||
|
||||
m_currentVal = -(tempResult + 1);
|
||||
}
|
||||
m_currentVal = -((m_currentVal ^ GetChopNumber()) + 1);
|
||||
}
|
||||
|
||||
if (radixtype >= RadixType::Hex && radixtype <= RadixType::Binary)
|
||||
|
@ -39,7 +32,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidt
|
|||
if (numwidth >= NUM_WIDTH::QWORD_WIDTH && numwidth <= NUM_WIDTH::BYTE_WIDTH)
|
||||
{
|
||||
m_numwidth = numwidth;
|
||||
m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(numwidth);
|
||||
m_dwWordBitWidth = DwWordBitWidthFromNumWidth(numwidth);
|
||||
}
|
||||
|
||||
// inform ratpak that a change in base or precision has occurred
|
||||
|
@ -50,7 +43,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidt
|
|||
DisplayNum();
|
||||
}
|
||||
|
||||
int32_t CCalcEngine::DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth)
|
||||
uint32_t CCalcEngine::DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth)
|
||||
{
|
||||
switch (numwidth)
|
||||
{
|
||||
|
@ -85,16 +78,16 @@ uint32_t CCalcEngine::NRadixFromRadixType(RadixType radixtype)
|
|||
// Toggles a given bit into the number representation. returns true if it changed it actually.
|
||||
bool CCalcEngine::TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno)
|
||||
{
|
||||
uint32_t wmax = DwWordBitWidthFromeNumWidth(m_numwidth);
|
||||
uint32_t wmax = DwWordBitWidthFromNumWidth(m_numwidth);
|
||||
if (wbitno >= wmax)
|
||||
{
|
||||
return false; // ignore error cant happen
|
||||
return false; // ignore error can't happen
|
||||
}
|
||||
|
||||
Rational result = Integer(rat);
|
||||
|
||||
// Remove any variance in how 0 could be represented in rat e.g. -0, 0/n, etc.
|
||||
result = (result != 0 ? result : 0);
|
||||
result = result != 0 ? result : 0;
|
||||
|
||||
// XOR the result with 2^wbitno power
|
||||
rat = result ^ Pow(2, static_cast<int32_t>(wbitno));
|
||||
|
@ -159,13 +152,13 @@ void CCalcEngine::UpdateMaxIntDigits()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_cIntDigitsSav = m_dwWordBitWidth / CCalcEngine::QuickLog2(m_radix);
|
||||
m_cIntDigitsSav = m_dwWordBitWidth / QuickLog2(m_radix);
|
||||
}
|
||||
}
|
||||
|
||||
void CCalcEngine::ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision)
|
||||
{
|
||||
if (10 == radix)
|
||||
if (radix == 10)
|
||||
{
|
||||
ChangeConstants(radix, precision); // Base 10 precision for internal computing still needs to be 32, to
|
||||
// take care of decimals precisely. For eg. to get the HI word of a qword, we do a rsh, which depends on getting
|
||||
|
@ -182,5 +175,5 @@ void CCalcEngine::ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t
|
|||
void CCalcEngine::BaseOrPrecisionChanged()
|
||||
{
|
||||
UpdateMaxIntDigits();
|
||||
CCalcEngine::ChangeBaseConstants(m_radix, m_cIntDigitsSav, m_precision);
|
||||
ChangeBaseConstants(m_radix, m_cIntDigitsSav, m_precision);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ using namespace CalculationManager;
|
|||
|
||||
namespace
|
||||
{
|
||||
static wstring GetGeneratedExpression(const vector<pair<wstring, int>>& tokens)
|
||||
wstring GetGeneratedExpression(const vector<pair<wstring, int>>& tokens)
|
||||
{
|
||||
wstring expression;
|
||||
bool isFirst = true;
|
||||
|
@ -41,7 +41,7 @@ unsigned int CalculatorHistory::AddToHistory(
|
|||
_In_ shared_ptr<vector<shared_ptr<IExpressionCommand>>> const& commands,
|
||||
wstring_view result)
|
||||
{
|
||||
shared_ptr<HISTORYITEM> spHistoryItem = make_shared<HISTORYITEM>();
|
||||
const auto spHistoryItem = make_shared<HISTORYITEM>();
|
||||
|
||||
spHistoryItem->historyItemVector.spTokens = tokens;
|
||||
spHistoryItem->historyItemVector.spCommands = commands;
|
||||
|
|
|
@ -23,11 +23,11 @@ namespace CalculationManager
|
|||
class CalculatorHistory : public IHistoryDisplay
|
||||
{
|
||||
public:
|
||||
CalculatorHistory(const size_t maxSize);
|
||||
CalculatorHistory(size_t maxSize);
|
||||
unsigned int AddToHistory(
|
||||
_In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& spTokens,
|
||||
_In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& spCommands,
|
||||
std::wstring_view result);
|
||||
std::wstring_view result) override;
|
||||
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistory();
|
||||
std::shared_ptr<HISTORYITEM> const& GetHistoryItem(unsigned int uIdx);
|
||||
void ClearHistory();
|
||||
|
|
|
@ -22,7 +22,6 @@ namespace CalculationManager
|
|||
, m_currentCalculatorEngine(nullptr)
|
||||
, m_resourceProvider(resourceProvider)
|
||||
, m_inHistoryItemLoadMode(false)
|
||||
, m_persistedPrimaryValue()
|
||||
, m_isExponentialFormat(false)
|
||||
, m_currentDegreeMode(Command::CommandNULL)
|
||||
, m_pStdHistory(new CalculatorHistory(MAX_HISTORY_ITEMS))
|
||||
|
@ -50,7 +49,7 @@ namespace CalculationManager
|
|||
m_displayCallback->SetIsInError(isError);
|
||||
}
|
||||
|
||||
void CalculatorManager::DisplayPasteError()
|
||||
void CalculatorManager::DisplayPasteError() const
|
||||
{
|
||||
m_currentCalculatorEngine->DisplayError(CALC_E_DOMAIN /*code for "Invalid input" error*/);
|
||||
}
|
||||
|
@ -211,14 +210,19 @@ namespace CalculationManager
|
|||
/// </summary>
|
||||
/// <param name="command">Enum Command</command>
|
||||
void CalculatorManager::SendCommand(_In_ Command command)
|
||||
{
|
||||
// When the expression line is cleared, we save the current state, which includes,
|
||||
// primary display, memory, and degree mode
|
||||
if (command == Command::CommandCLEAR || command == Command::CommandEQU || command == Command::ModeBasic || command == Command::ModeScientific
|
||||
|| command == Command::ModeProgrammer)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case Command::CommandCLEAR:
|
||||
// When the expression line is cleared, we save the current state, which includes,
|
||||
// primary display, memory, and degree mode
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandCLEAR));
|
||||
break;
|
||||
case Command::CommandEQU:
|
||||
// When the expression line is cleared, we save the current state, which includes,
|
||||
// primary display, memory, and degree mode
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandEQU));
|
||||
break;
|
||||
case Command::ModeBasic:
|
||||
this->SetStandardMode();
|
||||
break;
|
||||
|
@ -228,21 +232,18 @@ namespace CalculationManager
|
|||
case Command::ModeProgrammer:
|
||||
this->SetProgrammerMode();
|
||||
break;
|
||||
default:
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(command));
|
||||
}
|
||||
|
||||
InputChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (command == Command::CommandDEG || command == Command::CommandRAD || command == Command::CommandGRAD)
|
||||
{
|
||||
m_currentDegreeMode = command;
|
||||
}
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case Command::CommandDEG:
|
||||
m_currentDegreeMode = Command::CommandDEG;
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandDEG));
|
||||
break;
|
||||
case Command::CommandRAD:
|
||||
m_currentDegreeMode = Command::CommandRAD;
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandRAD));
|
||||
break;
|
||||
case Command::CommandGRAD:
|
||||
m_currentDegreeMode = Command::CommandGRAD;
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandGRAD));
|
||||
break;
|
||||
case Command::CommandASIN:
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandINV));
|
||||
m_currentCalculatorEngine->ProcessCommand(static_cast<OpCode>(Command::CommandSIN));
|
||||
|
@ -329,7 +330,7 @@ namespace CalculationManager
|
|||
|
||||
m_currentCalculatorEngine->ProcessCommand(IDC_STORE);
|
||||
|
||||
auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject();
|
||||
const auto memoryObjectPtr = m_currentCalculatorEngine->PersistedMemObject();
|
||||
if (memoryObjectPtr != nullptr)
|
||||
{
|
||||
m_memorizedNumbers.insert(m_memorizedNumbers.begin(), *memoryObjectPtr);
|
||||
|
@ -447,7 +448,7 @@ namespace CalculationManager
|
|||
/// Saved RAT number needs to be copied and passed in, as CCalcEngine destroyed the passed in RAT
|
||||
/// </summary>
|
||||
/// <param name="indexOfMemory">Index of the target memory</param>
|
||||
void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory)
|
||||
void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory) const
|
||||
{
|
||||
if (m_currentCalculatorEngine->FInErrorState())
|
||||
{
|
||||
|
@ -471,23 +472,25 @@ namespace CalculationManager
|
|||
}
|
||||
|
||||
auto memoryObject = m_currentCalculatorEngine->PersistedMemObject();
|
||||
if (memoryObject != nullptr)
|
||||
if (memoryObject == nullptr)
|
||||
{
|
||||
m_memorizedNumbers.at(indexOfMemory) = *memoryObject;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vector<shared_ptr<HISTORYITEM>> const& CalculatorManager::GetHistoryItems()
|
||||
m_memorizedNumbers.at(indexOfMemory) = *memoryObject;
|
||||
}
|
||||
|
||||
vector<shared_ptr<HISTORYITEM>> const& CalculatorManager::GetHistoryItems() const
|
||||
{
|
||||
return m_pHistory->GetHistory();
|
||||
}
|
||||
|
||||
vector<shared_ptr<HISTORYITEM>> const& CalculatorManager::GetHistoryItems(_In_ CalculatorMode mode)
|
||||
vector<shared_ptr<HISTORYITEM>> const& CalculatorManager::GetHistoryItems(_In_ CalculatorMode mode) const
|
||||
{
|
||||
return (mode == CalculatorMode::Standard) ? m_pStdHistory->GetHistory() : m_pSciHistory->GetHistory();
|
||||
return mode == CalculatorMode::Standard ? m_pStdHistory->GetHistory() : m_pSciHistory->GetHistory();
|
||||
}
|
||||
|
||||
shared_ptr<HISTORYITEM> const& CalculatorManager::GetHistoryItem(_In_ unsigned int uIdx)
|
||||
shared_ptr<HISTORYITEM> const& CalculatorManager::GetHistoryItem(_In_ unsigned int uIdx) const
|
||||
{
|
||||
return m_pHistory->GetHistoryItem(uIdx);
|
||||
}
|
||||
|
@ -497,17 +500,17 @@ namespace CalculationManager
|
|||
m_displayCallback->OnHistoryItemAdded(addedItemIndex);
|
||||
}
|
||||
|
||||
bool CalculatorManager::RemoveHistoryItem(_In_ unsigned int uIdx)
|
||||
bool CalculatorManager::RemoveHistoryItem(_In_ unsigned int uIdx) const
|
||||
{
|
||||
return m_pHistory->RemoveItem(uIdx);
|
||||
}
|
||||
|
||||
void CalculatorManager::ClearHistory()
|
||||
void CalculatorManager::ClearHistory() const
|
||||
{
|
||||
m_pHistory->ClearHistory();
|
||||
}
|
||||
|
||||
void CalculatorManager::SetRadix(RadixType iRadixType)
|
||||
void CalculatorManager::SetRadix(RadixType iRadixType) const
|
||||
{
|
||||
switch (iRadixType)
|
||||
{
|
||||
|
@ -529,7 +532,7 @@ namespace CalculationManager
|
|||
SetMemorizedNumbersString();
|
||||
}
|
||||
|
||||
void CalculatorManager::SetMemorizedNumbersString()
|
||||
void CalculatorManager::SetMemorizedNumbersString() const
|
||||
{
|
||||
vector<wstring> resultVector;
|
||||
for (auto const& memoryItem : m_memorizedNumbers)
|
||||
|
@ -545,7 +548,7 @@ namespace CalculationManager
|
|||
m_displayCallback->SetMemorizedNumbers(resultVector);
|
||||
}
|
||||
|
||||
CalculationManager::Command CalculatorManager::GetCurrentDegreeMode()
|
||||
Command CalculatorManager::GetCurrentDegreeMode()
|
||||
{
|
||||
if (m_currentDegreeMode == Command::CommandNULL)
|
||||
{
|
||||
|
@ -554,32 +557,32 @@ namespace CalculationManager
|
|||
return m_currentDegreeMode;
|
||||
}
|
||||
|
||||
wstring CalculatorManager::GetResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix)
|
||||
wstring CalculatorManager::GetResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix) const
|
||||
{
|
||||
return m_currentCalculatorEngine ? m_currentCalculatorEngine->GetCurrentResultForRadix(radix, precision, groupDigitsPerRadix) : L"";
|
||||
return m_currentCalculatorEngine != nullptr ? m_currentCalculatorEngine->GetCurrentResultForRadix(radix, precision, groupDigitsPerRadix) : L"";
|
||||
}
|
||||
|
||||
void CalculatorManager::SetPrecision(int32_t precision)
|
||||
void CalculatorManager::SetPrecision(int32_t precision) const
|
||||
{
|
||||
m_currentCalculatorEngine->ChangePrecision(precision);
|
||||
}
|
||||
|
||||
void CalculatorManager::UpdateMaxIntDigits()
|
||||
void CalculatorManager::UpdateMaxIntDigits() const
|
||||
{
|
||||
m_currentCalculatorEngine->UpdateMaxIntDigits();
|
||||
}
|
||||
|
||||
wchar_t CalculatorManager::DecimalSeparator()
|
||||
wchar_t CalculatorManager::DecimalSeparator() const
|
||||
{
|
||||
return m_currentCalculatorEngine ? m_currentCalculatorEngine->DecimalSeparator() : m_resourceProvider->GetCEngineString(L"sDecimal")[0];
|
||||
return m_currentCalculatorEngine != nullptr ? m_currentCalculatorEngine->DecimalSeparator() : m_resourceProvider->GetCEngineString(L"sDecimal")[0];
|
||||
}
|
||||
|
||||
bool CalculatorManager::IsEngineRecording()
|
||||
bool CalculatorManager::IsEngineRecording() const
|
||||
{
|
||||
return m_currentCalculatorEngine->FInRecordingState();
|
||||
}
|
||||
|
||||
bool CalculatorManager::IsInputEmpty()
|
||||
bool CalculatorManager::IsInputEmpty() const
|
||||
{
|
||||
return m_currentCalculatorEngine->IsInputEmpty();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace CalculationManager
|
|||
class CalculatorManager final : public ICalcDisplay
|
||||
{
|
||||
private:
|
||||
static const unsigned int m_maximumMemorySize = 100;
|
||||
static constexpr unsigned int m_maximumMemorySize = 100;
|
||||
ICalcDisplay* const m_displayCallback;
|
||||
CCalcEngine* m_currentCalculatorEngine;
|
||||
std::unique_ptr<CCalcEngine> m_scientificCalculatorEngine;
|
||||
|
@ -58,7 +58,7 @@ namespace CalculationManager
|
|||
bool m_isExponentialFormat;
|
||||
Command m_currentDegreeMode;
|
||||
|
||||
void MemorizedNumberSelect(_In_ unsigned int);
|
||||
void MemorizedNumberSelect(_In_ unsigned int) const;
|
||||
void MemorizedNumberChanged(_In_ unsigned int);
|
||||
|
||||
void LoadPersistedPrimaryValue();
|
||||
|
@ -78,7 +78,7 @@ namespace CalculationManager
|
|||
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
|
||||
void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
|
||||
void OnNoRightParenAdded() override;
|
||||
void DisplayPasteError();
|
||||
void DisplayPasteError() const;
|
||||
void MaxDigitsReached() override;
|
||||
void BinaryOperatorReceived() override;
|
||||
void MemoryItemChanged(unsigned int indexOfMemory) override;
|
||||
|
@ -98,20 +98,20 @@ namespace CalculationManager
|
|||
void MemorizedNumberClear(_In_ unsigned int);
|
||||
void MemorizedNumberClearAll();
|
||||
|
||||
bool IsEngineRecording();
|
||||
bool IsInputEmpty();
|
||||
void SetRadix(RadixType iRadixType);
|
||||
void SetMemorizedNumbersString();
|
||||
std::wstring GetResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix);
|
||||
void SetPrecision(int32_t precision);
|
||||
void UpdateMaxIntDigits();
|
||||
wchar_t DecimalSeparator();
|
||||
bool IsEngineRecording() const;
|
||||
bool IsInputEmpty() const;
|
||||
void SetRadix(RadixType iRadixType) const;
|
||||
void SetMemorizedNumbersString() const;
|
||||
std::wstring GetResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix) const;
|
||||
void SetPrecision(int32_t precision) const;
|
||||
void UpdateMaxIntDigits() const;
|
||||
wchar_t DecimalSeparator() const;
|
||||
|
||||
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistoryItems();
|
||||
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistoryItems(_In_ CalculatorMode mode);
|
||||
std::shared_ptr<HISTORYITEM> const& GetHistoryItem(_In_ unsigned int uIdx);
|
||||
bool RemoveHistoryItem(_In_ unsigned int uIdx);
|
||||
void ClearHistory();
|
||||
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistoryItems() const;
|
||||
std::vector<std::shared_ptr<HISTORYITEM>> const& GetHistoryItems(_In_ CalculatorMode mode) const;
|
||||
std::shared_ptr<HISTORYITEM> const& GetHistoryItem(_In_ unsigned int uIdx) const;
|
||||
bool RemoveHistoryItem(_In_ unsigned int uIdx) const;
|
||||
void ClearHistory() const;
|
||||
size_t MaxHistorySize() const
|
||||
{
|
||||
return m_pHistory->MaxHistorySize();
|
||||
|
|
|
@ -10,9 +10,7 @@ namespace CalculationManager
|
|||
class IResourceProvider
|
||||
{
|
||||
public:
|
||||
virtual ~IResourceProvider()
|
||||
{
|
||||
}
|
||||
virtual ~IResourceProvider() = default;
|
||||
|
||||
// Should return a string from the resource table for strings used
|
||||
// by the calculation engine. The strings that must be defined
|
||||
|
|
|
@ -104,7 +104,6 @@ COpndCommand::COpndCommand(shared_ptr<vector<int>> const& commands, bool fNegati
|
|||
, m_fSciFmt(fSciFmt)
|
||||
, m_fDecimal(fDecimal)
|
||||
, m_fInitialized(false)
|
||||
, m_value{}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -143,7 +142,7 @@ void COpndCommand::AppendCommand(int command)
|
|||
|
||||
void COpndCommand::ToggleSign()
|
||||
{
|
||||
for (int nOpCode : *m_commands)
|
||||
for (const int nOpCode : *m_commands)
|
||||
{
|
||||
if (nOpCode != IDC_0)
|
||||
{
|
||||
|
@ -169,9 +168,7 @@ void COpndCommand::RemoveFromEnd()
|
|||
}
|
||||
else
|
||||
{
|
||||
int nOpCode = m_commands->at(nCommands - 1);
|
||||
|
||||
if (nOpCode == IDC_PNT)
|
||||
if (m_commands->at(nCommands - 1) == IDC_PNT)
|
||||
{
|
||||
m_fDecimal = false;
|
||||
}
|
||||
|
@ -212,14 +209,14 @@ void COpndCommand::ClearAllAndAppendCommand(CalculationManager::Command command)
|
|||
|
||||
const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
|
||||
{
|
||||
static const wchar_t chZero = L'0';
|
||||
static constexpr wchar_t chZero = L'0';
|
||||
|
||||
const size_t nCommands = m_commands->size();
|
||||
m_token.clear();
|
||||
|
||||
for (size_t i = 0; i < nCommands; i++)
|
||||
{
|
||||
int nOpCode = (*m_commands)[i];
|
||||
auto nOpCode = (*m_commands)[i];
|
||||
|
||||
if (nOpCode == IDC_PNT)
|
||||
{
|
||||
|
@ -228,8 +225,7 @@ const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
|
|||
else if (nOpCode == IDC_EXP)
|
||||
{
|
||||
m_token += chExp;
|
||||
int nextOpCode = m_commands->at(i + 1);
|
||||
if (nextOpCode != IDC_SIGN)
|
||||
if (m_commands->at(i + 1) != IDC_SIGN)
|
||||
{
|
||||
m_token += chPlus;
|
||||
}
|
||||
|
@ -240,8 +236,7 @@ const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
|
|||
}
|
||||
else
|
||||
{
|
||||
wstring num = to_wstring(nOpCode - IDC_0);
|
||||
m_token.append(num);
|
||||
m_token.append(to_wstring(nOpCode - IDC_0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,7 +268,7 @@ const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
|
|||
return m_token;
|
||||
}
|
||||
|
||||
wstring COpndCommand::GetString(uint32_t radix, int32_t precision)
|
||||
wstring COpndCommand::GetString(uint32_t radix, int32_t precision) const
|
||||
{
|
||||
if (m_fInitialized)
|
||||
{
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
const std::wstring& GetToken(wchar_t decimalSymbol) override;
|
||||
CalculationManager::CommandType GetCommandType() const override;
|
||||
void Accept(_In_ ISerializeCommandVisitor& commandVisitor) override;
|
||||
std::wstring GetString(uint32_t radix, int32_t precision);
|
||||
std::wstring GetString(uint32_t radix, int32_t precision) const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::vector<int>> m_commands;
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
class IBinaryCommand : public IOperatorCommand
|
||||
{
|
||||
public:
|
||||
virtual void SetCommand(int command) override = 0;
|
||||
void SetCommand(int command) override = 0;
|
||||
virtual int GetCommand() const = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -56,14 +56,14 @@ public:
|
|||
CCalcEngine(
|
||||
bool fPrecedence,
|
||||
bool fIntegerMode,
|
||||
CalculationManager::IResourceProvider* const pResourceProvider,
|
||||
CalculationManager::IResourceProvider* pResourceProvider,
|
||||
__in_opt ICalcDisplay* pCalcDisplay,
|
||||
__in_opt std::shared_ptr<IHistoryDisplay> pHistoryDisplay);
|
||||
void ProcessCommand(OpCode wID);
|
||||
void DisplayError(uint32_t nError);
|
||||
std::unique_ptr<CalcEngine::Rational> PersistedMemObject();
|
||||
void PersistedMemObject(CalcEngine::Rational const& memObject);
|
||||
bool FInErrorState()
|
||||
bool FInErrorState() const
|
||||
{
|
||||
return m_bError;
|
||||
}
|
||||
|
@ -71,21 +71,21 @@ public:
|
|||
{
|
||||
return m_input.IsEmpty() && (m_numberString.empty() || m_numberString == L"0");
|
||||
}
|
||||
bool FInRecordingState()
|
||||
bool FInRecordingState() const
|
||||
{
|
||||
return m_bRecord;
|
||||
}
|
||||
void SettingsChanged();
|
||||
bool IsCurrentTooBigForTrig();
|
||||
uint32_t GetCurrentRadix();
|
||||
bool IsCurrentTooBigForTrig() const;
|
||||
uint32_t GetCurrentRadix() const;
|
||||
std::wstring GetCurrentResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix);
|
||||
void ChangePrecision(int32_t precision)
|
||||
{
|
||||
m_precision = precision;
|
||||
ChangeConstants(m_radix, precision);
|
||||
}
|
||||
std::wstring GroupDigitsPerRadix(std::wstring_view numberString, uint32_t radix);
|
||||
std::wstring GetStringForDisplay(CalcEngine::Rational const& rat, uint32_t radix);
|
||||
std::wstring GroupDigitsPerRadix(std::wstring_view numberString, uint32_t radix) const;
|
||||
std::wstring GetStringForDisplay(CalcEngine::Rational const& rat, uint32_t radix) const;
|
||||
void UpdateMaxIntDigits();
|
||||
wchar_t DecimalSeparator() const;
|
||||
|
||||
|
@ -149,38 +149,38 @@ private:
|
|||
int m_nLastCom; // Last command entered.
|
||||
AngleType m_angletype; // Current Angle type when in dec mode. one of deg, rad or grad
|
||||
NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode.
|
||||
int32_t m_dwWordBitWidth; // # of bits in currently selected word size
|
||||
uint32_t m_dwWordBitWidth; // # of bits in currently selected word size
|
||||
|
||||
std::unique_ptr<std::mt19937> m_randomGeneratorEngine;
|
||||
std::unique_ptr<std::uniform_real_distribution<>> m_distr;
|
||||
|
||||
uint64_t m_carryBit;
|
||||
uint64_t m_carryBit{};
|
||||
|
||||
CHistoryCollector m_HistoryCollector; // Accumulator of each line of history as various commands are processed
|
||||
|
||||
std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement
|
||||
std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers
|
||||
static std::unordered_map<std::wstring_view, std::wstring> s_engineStrings; // the string table shared across all instances
|
||||
wchar_t m_decimalSeparator;
|
||||
wchar_t m_decimalSeparator{};
|
||||
wchar_t m_groupSeparator;
|
||||
|
||||
private:
|
||||
void ProcessCommandWorker(OpCode wParam);
|
||||
void ResolveHighestPrecedenceOperation();
|
||||
void HandleErrorCommand(OpCode idc);
|
||||
void HandleMaxDigitsReached();
|
||||
void DisplayNum(void);
|
||||
void HandleMaxDigitsReached() const;
|
||||
void DisplayNum();
|
||||
int IsNumberInvalid(const std::wstring& numberString, int iMaxExp, int iMaxMantissa, uint32_t radix) const;
|
||||
void DisplayAnnounceBinaryOperator();
|
||||
void SetPrimaryDisplay(const std::wstring& szText, bool isError = false);
|
||||
void DisplayAnnounceBinaryOperator() const;
|
||||
void SetPrimaryDisplay(const std::wstring& szText, bool isError = false) const;
|
||||
void ClearTemporaryValues();
|
||||
void ClearDisplay();
|
||||
CalcEngine::Rational TruncateNumForIntMath(CalcEngine::Rational const& rat);
|
||||
void ClearDisplay() const;
|
||||
CalcEngine::Rational TruncateNumForIntMath(CalcEngine::Rational const& rat) const;
|
||||
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op);
|
||||
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
|
||||
void SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidth);
|
||||
int32_t DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth);
|
||||
uint32_t NRadixFromRadixType(RadixType radixtype);
|
||||
static uint32_t DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth);
|
||||
static uint32_t NRadixFromRadixType(RadixType radixtype);
|
||||
double GenerateRandomNumber();
|
||||
|
||||
bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno);
|
||||
|
@ -197,7 +197,7 @@ private:
|
|||
}
|
||||
|
||||
static std::vector<uint32_t> DigitGroupingStringToGroupingVector(std::wstring_view groupingString);
|
||||
std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false);
|
||||
std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false) const;
|
||||
|
||||
static int QuickLog2(int iNum);
|
||||
static void ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision);
|
||||
|
|
|
@ -14,18 +14,17 @@ namespace CalcEngine
|
|||
{
|
||||
public:
|
||||
CalcNumSec()
|
||||
: value()
|
||||
, m_isNegative(false)
|
||||
: m_isNegative(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Clear();
|
||||
bool IsEmpty()
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return value.empty();
|
||||
}
|
||||
|
||||
bool IsNegative()
|
||||
bool IsNegative() const
|
||||
{
|
||||
return m_isNegative;
|
||||
}
|
||||
|
@ -53,22 +52,20 @@ namespace CalcEngine
|
|||
, m_hasDecimal(false)
|
||||
, m_decPtIndex(0)
|
||||
, m_decSymbol(decSymbol)
|
||||
, m_base()
|
||||
, m_exponent()
|
||||
{
|
||||
}
|
||||
|
||||
void Clear();
|
||||
bool TryToggleSign(bool isIntegerMode, std::wstring_view maxNumStr);
|
||||
bool TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, std::wstring_view maxNumStr, int32_t wordBitWidth, int maxDigits);
|
||||
bool TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, std::wstring_view maxNumStr, uint32_t wordBitWidth, int maxDigits);
|
||||
bool TryAddDecimalPt();
|
||||
bool HasDecimalPt();
|
||||
bool HasDecimalPt() const;
|
||||
bool TryBeginExponent();
|
||||
void Backspace();
|
||||
void SetDecimalSymbol(wchar_t decSymbol);
|
||||
bool IsEmpty();
|
||||
std::wstring ToString(uint32_t radix);
|
||||
Rational ToRational(uint32_t radix, int32_t precision);
|
||||
bool IsEmpty() const;
|
||||
std::wstring ToString(uint32_t radix) const;
|
||||
Rational ToRational(uint32_t radix, int32_t precision) const;
|
||||
|
||||
private:
|
||||
bool m_hasExponent;
|
||||
|
|
|
@ -21,15 +21,15 @@ public:
|
|||
~CHistoryCollector();
|
||||
void AddOpndToHistory(std::wstring_view numStr, CalcEngine::Rational const& rat, bool fRepetition = false);
|
||||
void RemoveLastOpndFromHistory();
|
||||
void AddBinOpToHistory(int nOpCode, bool isIntgerMode, bool fNoRepetition = true);
|
||||
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode);
|
||||
void AddBinOpToHistory(int nOpCode, bool isIntegerMode, bool fNoRepetition = true);
|
||||
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntegerMode);
|
||||
void AddUnaryOpToHistory(int nOpCode, bool fInv, AngleType angletype);
|
||||
void AddOpenBraceToHistory();
|
||||
void AddCloseBraceToHistory();
|
||||
void PushLastOpndStart(int ichOpndStart = -1);
|
||||
void PopLastOpndStart();
|
||||
void EnclosePrecInversionBrackets();
|
||||
bool FOpndAddedToHistory();
|
||||
bool FOpndAddedToHistory() const;
|
||||
void CompleteHistoryLine(std::wstring_view numStr);
|
||||
void CompleteEquation(std::wstring_view numStr);
|
||||
void ClearHistoryLine(std::wstring_view errStr);
|
||||
|
@ -44,12 +44,12 @@ private:
|
|||
int m_iCurLineHistStart; // index of the beginning of the current equation
|
||||
// a sort of state, set to the index before 2 after 2 in the expression 2 + 3 say. Useful for auto correct portion of history and for
|
||||
// attaching the unary op around the last operand
|
||||
int m_lastOpStartIndex; // index of the beginning of the last operand added to the history
|
||||
int m_lastBinOpStartIndex; // index of the beginning of the last binary operator added to the history
|
||||
int m_lastOpStartIndex{}; // index of the beginning of the last operand added to the history
|
||||
int m_lastBinOpStartIndex{}; // index of the beginning of the last binary operator added to the history
|
||||
std::array<int, MAXPRECDEPTH>
|
||||
m_operandIndices; // Stack of index of opnd's beginning for each '('. A parallel array to m_hnoParNum, but abstracted independently of that
|
||||
int m_curOperandIndex; // Stack index for the above stack
|
||||
bool m_bLastOpndBrace; // iff the last opnd in history is already braced so we can avoid putting another one for unary operator
|
||||
m_operandIndices{}; // Stack of index of opnd's beginning for each '('. A parallel array to m_hnoParNum, but abstracted independently of that
|
||||
int m_curOperandIndex{}; // Stack index for the above stack
|
||||
bool m_bLastOpndBrace{}; // iff the last opnd in history is already braced so we can avoid putting another one for unary operator
|
||||
wchar_t m_decimalSymbol;
|
||||
std::shared_ptr<std::vector<std::pair<std::wstring, int>>> m_spTokens;
|
||||
std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
|
||||
|
@ -57,8 +57,8 @@ private:
|
|||
private:
|
||||
void ReinitHistory();
|
||||
int IchAddSzToEquationSz(std::wstring_view str, int icommandIndex);
|
||||
void TruncateEquationSzFromIch(int ich);
|
||||
void SetExpressionDisplay();
|
||||
void InsertSzInEquationSz(std::wstring_view str, int icommandIndex, int ich);
|
||||
std::shared_ptr<std::vector<int>> GetOperandCommandsFromString(std::wstring_view numStr);
|
||||
void TruncateEquationSzFromIch(int ich) const;
|
||||
void SetExpressionDisplay() const;
|
||||
void InsertSzInEquationSz(std::wstring_view str, int icommandIndex, int ich) const;
|
||||
std::shared_ptr<std::vector<int>> GetOperandCommandsFromString(std::wstring_view numStr) const;
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
class IHistoryDisplay
|
||||
{
|
||||
public:
|
||||
virtual ~IHistoryDisplay(){};
|
||||
virtual ~IHistoryDisplay() = default;
|
||||
virtual unsigned int AddToHistory(
|
||||
_In_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_In_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands,
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace CalcEngine
|
|||
public:
|
||||
Rational() noexcept;
|
||||
Rational(Number const& n) noexcept;
|
||||
Rational(Number const& p, Number const& q) noexcept;
|
||||
Rational(Number p, Number q) noexcept;
|
||||
Rational(int32_t i);
|
||||
Rational(uint32_t ui);
|
||||
Rational(uint64_t ui);
|
||||
|
|
|
@ -8,22 +8,22 @@ namespace UnitConversionManager::NumberFormattingUtils
|
|||
/// <summary>
|
||||
/// Trims out any trailing zeros or decimals in the given input string
|
||||
/// </summary>
|
||||
/// <param name="number">number to trim</param>
|
||||
void TrimTrailingZeros(_Inout_ wstring& number)
|
||||
/// <param name="input">input to trim</param>
|
||||
void TrimTrailingZeros(_Inout_ wstring& input)
|
||||
{
|
||||
if (number.find(L'.') == wstring::npos)
|
||||
if (input.find(L'.') == wstring::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto i = number.find_last_not_of(L'0'); i != wstring::npos)
|
||||
if (const auto i = input.find_last_not_of(L'0'); i != wstring::npos)
|
||||
{
|
||||
number.erase(number.cbegin() + i + 1, number.cend());
|
||||
input.erase(input.cbegin() + i + 1, input.cend());
|
||||
}
|
||||
|
||||
if (number.back() == L'.')
|
||||
if (input.back() == L'.')
|
||||
{
|
||||
number.pop_back();
|
||||
input.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,14 +56,14 @@ namespace UnitConversionManager::NumberFormattingUtils
|
|||
/// <summary>
|
||||
/// Rounds the given double to the given number of significant digits
|
||||
/// </summary>
|
||||
/// <param name="num">input double</param>
|
||||
/// <param name="value">input double</param>
|
||||
/// <param name="numSignificant">unsigned int number of significant digits to round to</param>
|
||||
wstring RoundSignificantDigits(double num, unsigned int numSignificant)
|
||||
wstring RoundSignificantDigits(double value, unsigned int numSignificant)
|
||||
{
|
||||
wstringstream out(wstringstream::out);
|
||||
out << fixed;
|
||||
out.precision(numSignificant);
|
||||
out << num;
|
||||
out << value;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
// This format is based loosely on an OLE HRESULT and is compatible with the
|
||||
// SUCCEEDED and FAILED macros as well as the HRESULT_CODE macro
|
||||
|
||||
typedef int32_t ResultCode;
|
||||
using ResultCode = int32_t;
|
||||
|
||||
// CALC_E_DIVIDEBYZERO
|
||||
//
|
||||
|
|
|
@ -117,7 +117,7 @@ void _mulnumx(PNUMBER* pa, PNUMBER b)
|
|||
for (ibdigit = b->cdigit; ibdigit > 0; ibdigit--)
|
||||
{
|
||||
cy = 0;
|
||||
mcy = (uint64_t)da * (*ptrb);
|
||||
mcy = static_cast<uint64_t>(da) * *ptrb;
|
||||
if (mcy)
|
||||
{
|
||||
icdigit = 0;
|
||||
|
@ -131,10 +131,10 @@ void _mulnumx(PNUMBER* pa, PNUMBER b)
|
|||
while (mcy || cy)
|
||||
{
|
||||
// update carry from addition(s) and multiply.
|
||||
cy += (TWO_MANTTYPE)ptrc[icdigit] + ((uint32_t)mcy & ((uint32_t)~BASEX));
|
||||
cy += static_cast<TWO_MANTTYPE>(ptrc[icdigit]) + (static_cast<uint32_t>(mcy) & ~BASEX);
|
||||
|
||||
// update result digit from
|
||||
ptrc[icdigit++] = (MANTTYPE)((uint32_t)cy & ((uint32_t)~BASEX));
|
||||
ptrc[icdigit++] = static_cast<uint32_t>(cy) & ~BASEX;
|
||||
|
||||
// update carries from
|
||||
mcy >>= BASEXPWR;
|
||||
|
@ -286,7 +286,7 @@ void _divnumx(PNUMBER* pa, PNUMBER b, int32_t precision)
|
|||
|
||||
// Create c (the divide answer) and set up exponent and sign.
|
||||
createnum(c, thismax + 1);
|
||||
c->exp = (a->cdigit + a->exp) - (b->cdigit + b->exp) + 1;
|
||||
c->exp = a->cdigit + a->exp - (b->cdigit + b->exp) + 1;
|
||||
c->sign = a->sign * b->sign;
|
||||
|
||||
ptrc = c->mant + thismax;
|
||||
|
@ -298,7 +298,7 @@ void _divnumx(PNUMBER* pa, PNUMBER b, int32_t precision)
|
|||
|
||||
while (cdigits++ < thismax && !zernum(rem))
|
||||
{
|
||||
int32_t digit = 0;
|
||||
uint32_t digit = 0;
|
||||
*ptrc = 0;
|
||||
while (!lessnum(rem, b))
|
||||
{
|
||||
|
@ -334,7 +334,7 @@ void _divnumx(PNUMBER* pa, PNUMBER b, int32_t precision)
|
|||
cdigits--;
|
||||
if (c->mant != ++ptrc)
|
||||
{
|
||||
memmove(c->mant, ptrc, (int)(cdigits * sizeof(MANTTYPE)));
|
||||
memmove(c->mant, ptrc, cdigits * sizeof(MANTTYPE));
|
||||
}
|
||||
|
||||
if (!cdigits)
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include "winerror_cross_platform.h"
|
||||
#include <sstream>
|
||||
#include <cstring> // for memmove, memcpy
|
||||
#include "ratpak.h"
|
||||
|
||||
|
@ -69,9 +68,9 @@ namespace
|
|||
int32_t hr = CALC_INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
*pulResult = CALC_ULONG_ERROR;
|
||||
|
||||
if ((ulAugend + ulAddend) >= ulAugend)
|
||||
if (ulAugend + ulAddend >= ulAugend)
|
||||
{
|
||||
*pulResult = (ulAugend + ulAddend);
|
||||
*pulResult = ulAugend + ulAddend;
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
|
@ -85,7 +84,7 @@ namespace
|
|||
|
||||
if (ullOperand <= UINT32_MAX)
|
||||
{
|
||||
*pulResult = (uint32_t)ullOperand;
|
||||
*pulResult = static_cast<uint32_t>(ullOperand);
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
|
@ -130,7 +129,7 @@ void* zmalloc(size_t a)
|
|||
|
||||
void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src)
|
||||
{
|
||||
memcpy(dest, src, (int)(sizeof(NUMBER) + ((src)->cdigit) * (sizeof(MANTTYPE))));
|
||||
memcpy(dest, src, sizeof(NUMBER) + src->cdigit * sizeof(MANTTYPE));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -148,10 +147,12 @@ void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src)
|
|||
void _destroynum(_Frees_ptr_opt_ PNUMBER pnum)
|
||||
|
||||
{
|
||||
if (pnum != nullptr)
|
||||
if (pnum == nullptr)
|
||||
{
|
||||
free(pnum);
|
||||
return;
|
||||
}
|
||||
|
||||
free(pnum);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -170,12 +171,13 @@ void _destroynum(_Frees_ptr_opt_ PNUMBER pnum)
|
|||
void _destroyrat(_Frees_ptr_opt_ PRAT prat)
|
||||
|
||||
{
|
||||
if (prat != nullptr)
|
||||
if (prat == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
destroynum(prat->pp);
|
||||
destroynum(prat->pq);
|
||||
free(prat);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -200,17 +202,17 @@ PNUMBER _createnum(_In_ uint32_t size)
|
|||
if (SUCCEEDED(Calc_ULongAdd(size, 1, &cbAlloc)) && SUCCEEDED(Calc_ULongMult(cbAlloc, sizeof(MANTTYPE), &cbAlloc))
|
||||
&& SUCCEEDED(Calc_ULongAdd(cbAlloc, sizeof(NUMBER), &cbAlloc)))
|
||||
{
|
||||
pnumret = (PNUMBER)zmalloc(cbAlloc);
|
||||
pnumret = static_cast<PNUMBER>(zmalloc(cbAlloc));
|
||||
if (pnumret == nullptr)
|
||||
{
|
||||
throw(CALC_E_OUTOFMEMORY);
|
||||
throw CALC_E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw(CALC_E_INVALIDRANGE);
|
||||
throw CALC_E_INVALIDRANGE;
|
||||
}
|
||||
return (pnumret);
|
||||
return pnumret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -227,20 +229,20 @@ PNUMBER _createnum(_In_ uint32_t size)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
PRAT _createrat(void)
|
||||
PRAT _createrat()
|
||||
|
||||
{
|
||||
PRAT prat = nullptr;
|
||||
|
||||
prat = (PRAT)zmalloc(sizeof(RAT));
|
||||
prat = static_cast<PRAT>(zmalloc(sizeof(RAT)));
|
||||
|
||||
if (prat == nullptr)
|
||||
{
|
||||
throw(CALC_E_OUTOFMEMORY);
|
||||
throw CALC_E_OUTOFMEMORY;
|
||||
}
|
||||
prat->pp = nullptr;
|
||||
prat->pq = nullptr;
|
||||
return (prat);
|
||||
return prat;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -283,7 +285,7 @@ PRAT numtorat(_In_ PNUMBER pin, uint32_t radix)
|
|||
destroynum(pnRadixn);
|
||||
destroynum(qnRadixn);
|
||||
|
||||
return (pout);
|
||||
return pout;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -303,26 +305,26 @@ PRAT numtorat(_In_ PNUMBER pin, uint32_t radix)
|
|||
PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision)
|
||||
|
||||
{
|
||||
PNUMBER sum = i32tonum(0, radix);
|
||||
PNUMBER powofnRadix = i32tonum(BASEX, radix);
|
||||
PNUMBER sum = Ui32tonum(0, radix);
|
||||
PNUMBER powofnRadix = Ui32tonum(BASEX, radix);
|
||||
|
||||
// A large penalty is paid for conversion of digits no one will see anyway.
|
||||
// limit the digits to the minimum of the existing precision or the
|
||||
// requested precision.
|
||||
uint32_t cdigits = precision + 1;
|
||||
if (cdigits > (uint32_t)a->cdigit)
|
||||
int32_t cdigits = precision + 1;
|
||||
if (cdigits > a->cdigit)
|
||||
{
|
||||
cdigits = (uint32_t)a->cdigit;
|
||||
cdigits = a->cdigit;
|
||||
}
|
||||
|
||||
// scale by the internal base to the internal exponent offset of the LSD
|
||||
numpowi32(&powofnRadix, a->exp + (a->cdigit - cdigits), radix, precision);
|
||||
|
||||
// Loop over all the relative digits from MSD to LSD
|
||||
for (MANTTYPE* ptr = &(a->mant[a->cdigit - 1]); cdigits > 0; ptr--, cdigits--)
|
||||
for (MANTTYPE* ptr = &a->mant[a->cdigit - 1]; cdigits > 0; ptr--, cdigits--)
|
||||
{
|
||||
// Loop over all the bits from MSB to LSB
|
||||
for (uint32_t bitmask = BASEX / 2; bitmask > 0; bitmask /= 2)
|
||||
for (auto bitmask = BASEX >> 1; bitmask > 0; bitmask >>= 1)
|
||||
{
|
||||
addnum(&sum, sum, radix);
|
||||
if (*ptr & bitmask)
|
||||
|
@ -337,7 +339,7 @@ PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision)
|
|||
|
||||
destroynum(powofnRadix);
|
||||
sum->sign = a->sign;
|
||||
return (sum);
|
||||
return sum;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -356,21 +358,21 @@ PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision)
|
|||
|
||||
PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix)
|
||||
{
|
||||
PNUMBER pnumret = i32tonum(0, BASEX); // pnumret is the number in internal form.
|
||||
PNUMBER num_radix = i32tonum(radix, BASEX);
|
||||
PNUMBER pnumret = Ui32tonum(0, BASEX); // pnumret is the number in internal form.
|
||||
PNUMBER num_radix = Ui32tonum(radix, BASEX);
|
||||
MANTTYPE* ptrdigit = a->mant; // pointer to digit being worked on.
|
||||
|
||||
// Digits are in reverse order, back over them LSD first.
|
||||
ptrdigit += a->cdigit - 1;
|
||||
|
||||
PNUMBER thisdigit = nullptr; // thisdigit holds the current digit of a
|
||||
PNUMBER thisdigit; // thisdigit holds the current digit of a
|
||||
for (int32_t idigit = 0; idigit < a->cdigit; idigit++)
|
||||
{
|
||||
mulnumx(&pnumret, num_radix);
|
||||
// WARNING:
|
||||
// This should just smack in each digit into a 'special' thisdigit.
|
||||
// and not do the overhead of recreating the number type each time.
|
||||
thisdigit = i32tonum(*ptrdigit--, BASEX);
|
||||
thisdigit = Ui32tonum(*ptrdigit--, BASEX);
|
||||
addnum(&pnumret, thisdigit, BASEX);
|
||||
destroynum(thisdigit);
|
||||
}
|
||||
|
@ -386,7 +388,7 @@ PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix)
|
|||
// And propagate the sign.
|
||||
pnumret->sign = a->sign;
|
||||
|
||||
return (pnumret);
|
||||
return pnumret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -611,12 +613,12 @@ wchar_t NormalizeCharDigit(wchar_t c, uint32_t radix)
|
|||
|
||||
PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precision)
|
||||
{
|
||||
int32_t expSign = 1L; // expSign is exponent sign ( +/- 1 )
|
||||
int32_t expValue = 0L; // expValue is exponent mantissa, should be unsigned
|
||||
int32_t expSign = 1; // expSign is exponent sign ( +/- 1 )
|
||||
int32_t expValue = 0; // expValue is exponent mantissa, should be unsigned
|
||||
|
||||
PNUMBER pnumret = nullptr;
|
||||
createnum(pnumret, static_cast<uint32_t>(numberString.length()));
|
||||
pnumret->sign = 1L;
|
||||
pnumret->sign = 1;
|
||||
pnumret->cdigit = 0;
|
||||
pnumret->exp = 0;
|
||||
MANTTYPE* pmant = pnumret->mant + numberString.length() - 1;
|
||||
|
@ -625,7 +627,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
|||
for (const auto& c : numberString)
|
||||
{
|
||||
// If the character is the decimal separator, use L'.' for the purposes of the state machine.
|
||||
wchar_t curChar = (c == g_decimalSeparator ? L'.' : c);
|
||||
wchar_t curChar = c == g_decimalSeparator ? L'.' : c;
|
||||
|
||||
// Switch states based on the character we encountered
|
||||
switch (curChar)
|
||||
|
@ -658,11 +660,11 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
|||
switch (state)
|
||||
{
|
||||
case MANTS:
|
||||
pnumret->sign = (curChar == L'-') ? -1 : 1;
|
||||
pnumret->sign = curChar == L'-' ? -1 : 1;
|
||||
break;
|
||||
case EXPSZ:
|
||||
case EXPS:
|
||||
expSign = (curChar == L'-') ? -1 : 1;
|
||||
expSign = curChar == L'-' ? -1 : 1;
|
||||
break;
|
||||
case EXPDZ:
|
||||
case EXPD:
|
||||
|
@ -758,11 +760,11 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
|
|||
PRAT i32torat(int32_t ini32)
|
||||
|
||||
{
|
||||
PRAT pratret = nullptr;
|
||||
PRAT pratret;
|
||||
createrat(pratret);
|
||||
pratret->pp = i32tonum(ini32, BASEX);
|
||||
pratret->pq = i32tonum(1L, BASEX);
|
||||
return (pratret);
|
||||
return pratret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -782,11 +784,11 @@ PRAT i32torat(int32_t ini32)
|
|||
PRAT Ui32torat(uint32_t inui32)
|
||||
|
||||
{
|
||||
PRAT pratret = nullptr;
|
||||
PRAT pratret;
|
||||
createrat(pratret);
|
||||
pratret->pp = Ui32tonum(inui32, BASEX);
|
||||
pratret->pq = i32tonum(1L, BASEX);
|
||||
return (pratret);
|
||||
return pratret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -806,7 +808,7 @@ PNUMBER i32tonum(int32_t ini32, uint32_t radix)
|
|||
|
||||
{
|
||||
MANTTYPE* pmant;
|
||||
PNUMBER pnumret = nullptr;
|
||||
PNUMBER pnumret;
|
||||
|
||||
createnum(pnumret, MAX_LONG_SIZE);
|
||||
pmant = pnumret->mant;
|
||||
|
@ -824,12 +826,12 @@ PNUMBER i32tonum(int32_t ini32, uint32_t radix)
|
|||
|
||||
do
|
||||
{
|
||||
*pmant++ = (MANTTYPE)(ini32 % radix);
|
||||
*pmant++ = static_cast<MANTTYPE>(ini32 % radix);
|
||||
ini32 /= radix;
|
||||
pnumret->cdigit++;
|
||||
} while (ini32);
|
||||
|
||||
return (pnumret);
|
||||
return pnumret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -849,7 +851,7 @@ PNUMBER i32tonum(int32_t ini32, uint32_t radix)
|
|||
PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix)
|
||||
{
|
||||
MANTTYPE* pmant;
|
||||
PNUMBER pnumret = nullptr;
|
||||
PNUMBER pnumret;
|
||||
|
||||
createnum(pnumret, MAX_LONG_SIZE);
|
||||
pmant = pnumret->mant;
|
||||
|
@ -859,12 +861,12 @@ PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix)
|
|||
|
||||
do
|
||||
{
|
||||
*pmant++ = (MANTTYPE)(ini32 % radix);
|
||||
*pmant++ = static_cast<MANTTYPE>(ini32 % radix);
|
||||
ini32 /= radix;
|
||||
pnumret->cdigit++;
|
||||
} while (ini32);
|
||||
|
||||
return (pnumret);
|
||||
return pnumret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -886,21 +888,21 @@ int32_t rattoi32(_In_ PRAT prat, uint32_t radix, int32_t precision)
|
|||
if (rat_gt(prat, rat_max_i32, precision) || rat_lt(prat, rat_min_i32, precision))
|
||||
{
|
||||
// Don't attempt rattoi32 of anything too big or small
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
|
||||
PRAT pint = nullptr;
|
||||
DUPRAT(pint, prat);
|
||||
|
||||
intrat(&pint, radix, precision);
|
||||
divnumx(&(pint->pp), pint->pq, precision);
|
||||
divnumx(&pint->pp, pint->pq, precision);
|
||||
DUPNUM(pint->pq, num_one);
|
||||
|
||||
int32_t lret = numtoi32(pint->pp, BASEX);
|
||||
|
||||
destroyrat(pint);
|
||||
|
||||
return (lret);
|
||||
return lret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -921,21 +923,21 @@ uint32_t rattoUi32(_In_ PRAT prat, uint32_t radix, int32_t precision)
|
|||
if (rat_gt(prat, rat_dword, precision) || rat_lt(prat, rat_zero, precision))
|
||||
{
|
||||
// Don't attempt rattoui32 of anything too big or small
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
|
||||
PRAT pint = nullptr;
|
||||
DUPRAT(pint, prat);
|
||||
|
||||
intrat(&pint, radix, precision);
|
||||
divnumx(&(pint->pp), pint->pq, precision);
|
||||
divnumx(&pint->pp, pint->pq, precision);
|
||||
DUPNUM(pint->pq, num_one);
|
||||
|
||||
uint32_t lret = numtoi32(pint->pp, BASEX); // This happens to work even if it is only signed
|
||||
|
||||
destroyrat(pint);
|
||||
|
||||
return (lret);
|
||||
return lret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -972,7 +974,7 @@ uint64_t rattoUi64(_In_ PRAT prat, uint32_t radix, int32_t precision)
|
|||
destroyrat(prat32);
|
||||
destroyrat(pint);
|
||||
|
||||
return (((uint64_t)hi << 32) | lo);
|
||||
return (static_cast<uint64_t>(hi) << 32) | lo;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -992,17 +994,16 @@ int32_t numtoi32(_In_ PNUMBER pnum, uint32_t radix)
|
|||
{
|
||||
int32_t lret = 0;
|
||||
|
||||
MANTTYPE* pmant = pnum->mant;
|
||||
pmant += pnum->cdigit - 1;
|
||||
MANTTYPE* pmant = pnum->mant + pnum->cdigit - 1;
|
||||
|
||||
int32_t expt = pnum->exp;
|
||||
for (int32_t length = pnum->cdigit; length > 0 && length + expt > 0; length--)
|
||||
auto expt = pnum->exp;
|
||||
for (auto length = pnum->cdigit; length > 0 && length + expt > 0; length--)
|
||||
{
|
||||
lret *= radix;
|
||||
lret += *(pmant--);
|
||||
lret += *pmant--;
|
||||
}
|
||||
|
||||
while (expt-- > 0)
|
||||
for (; expt > 0; --expt)
|
||||
{
|
||||
lret *= radix;
|
||||
}
|
||||
|
@ -1025,37 +1026,34 @@ int32_t numtoi32(_In_ PNUMBER pnum, uint32_t radix)
|
|||
|
||||
bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting)
|
||||
{
|
||||
bool fstrip = false;
|
||||
// point pmant to the LeastCalculatedDigit
|
||||
MANTTYPE* pmant = pnum->mant;
|
||||
int32_t cdigits = pnum->cdigit;
|
||||
// point pmant to the LSD
|
||||
if (cdigits > starting)
|
||||
{
|
||||
pmant += cdigits - starting;
|
||||
pmant = pmant + cdigits - starting;
|
||||
cdigits = starting;
|
||||
}
|
||||
|
||||
// Check we haven't gone too far, and we are still looking at zeros.
|
||||
while ((cdigits > 0) && !(*pmant))
|
||||
if (cdigits < 1 || *pmant != 0)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
// move to next significant digit and keep track of digits we can
|
||||
// ignore later.
|
||||
pmant++;
|
||||
cdigits--;
|
||||
fstrip = true;
|
||||
}
|
||||
} while (cdigits > 0 && *pmant == 0);
|
||||
|
||||
// If there are zeros to remove.
|
||||
if (fstrip)
|
||||
{
|
||||
// Remove them.
|
||||
memmove(pnum->mant, pmant, (int)(cdigits * sizeof(MANTTYPE)));
|
||||
// Remove the zeros
|
||||
memmove(pnum->mant, pmant, cdigits * sizeof(MANTTYPE));
|
||||
// And adjust exponent and digit count accordingly.
|
||||
pnum->exp += (pnum->cdigit - cdigits);
|
||||
pnum->exp += pnum->cdigit - cdigits;
|
||||
pnum->cdigit = cdigits;
|
||||
}
|
||||
return (fstrip);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1096,10 +1094,10 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
|||
// - if number is zero no rounding
|
||||
// - if number of digits is less than the maximum output no rounding
|
||||
PNUMBER round = nullptr;
|
||||
if (!zernum(pnum) && (pnum->cdigit >= precision || (length - exponent > precision && exponent >= -MAX_ZEROS_AFTER_DECIMAL)))
|
||||
if (!zernum(pnum) && (pnum->cdigit >= precision || length - exponent > precision && exponent >= -MAX_ZEROS_AFTER_DECIMAL))
|
||||
{
|
||||
// Otherwise round.
|
||||
round = i32tonum(radix, radix);
|
||||
round = Ui32tonum(radix, radix);
|
||||
divnum(&round, num_two, radix, precision);
|
||||
|
||||
// Make round number exponent one below the LSD for the number.
|
||||
|
@ -1119,7 +1117,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
|||
if (format == NumberFormat::Float)
|
||||
{
|
||||
// Figure out if the exponent will fill more space than the non-exponent field.
|
||||
if ((length - exponent > precision) || (exponent > precision + 3))
|
||||
if (length - exponent > precision || exponent > precision + 3)
|
||||
{
|
||||
if (exponent >= -MAX_ZEROS_AFTER_DECIMAL)
|
||||
{
|
||||
|
@ -1144,7 +1142,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
|||
if (round != nullptr)
|
||||
{
|
||||
addnum(&pnum, round, radix);
|
||||
int32_t offset = (pnum->cdigit + pnum->exp) - (round->cdigit + round->exp);
|
||||
int32_t offset = pnum->cdigit + pnum->exp - (round->cdigit + round->exp);
|
||||
destroynum(round);
|
||||
if (stripzeroesnum(pnum, offset))
|
||||
{
|
||||
|
@ -1164,14 +1162,14 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
|||
MANTTYPE* pmant = pnum->mant + pnum->cdigit - 1;
|
||||
// Case where too many digits are to the left of the decimal or
|
||||
// NumberFormat::Scientific or NumberFormat::Engineering was specified.
|
||||
if ((format == NumberFormat::Scientific) || (format == NumberFormat::Engineering))
|
||||
if (format == NumberFormat::Scientific || format == NumberFormat::Engineering)
|
||||
{
|
||||
useSciForm = true;
|
||||
if (eout != 0)
|
||||
{
|
||||
if (format == NumberFormat::Engineering)
|
||||
{
|
||||
exponent = (eout % 3);
|
||||
exponent = eout % 3;
|
||||
eout -= exponent;
|
||||
exponent++;
|
||||
|
||||
|
@ -1197,12 +1195,12 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
|||
wstring result;
|
||||
|
||||
// Make sure negative zeros aren't allowed.
|
||||
if ((pnum->sign == -1) && (length > 0))
|
||||
if (pnum->sign == -1 && length > 0)
|
||||
{
|
||||
result = L'-';
|
||||
}
|
||||
|
||||
if (exponent <= 0 && !useSciForm)
|
||||
if (exponent < 1 && !useSciForm)
|
||||
{
|
||||
result += L'0';
|
||||
result += g_decimalSeparator;
|
||||
|
@ -1217,32 +1215,30 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
|||
|
||||
while (length > 0)
|
||||
{
|
||||
exponent--;
|
||||
result += DIGITS[*pmant--];
|
||||
length--;
|
||||
|
||||
// Be more regular in using a decimal point.
|
||||
if (exponent == 0)
|
||||
if (--exponent == 0)
|
||||
{
|
||||
result += g_decimalSeparator;
|
||||
}
|
||||
}
|
||||
|
||||
while (exponent > 0)
|
||||
if (exponent > 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
result += L'0';
|
||||
exponent--;
|
||||
} while (--exponent > 0);
|
||||
// Be more regular in using a decimal point.
|
||||
if (exponent == 0)
|
||||
{
|
||||
result += g_decimalSeparator;
|
||||
}
|
||||
}
|
||||
|
||||
if (useSciForm)
|
||||
{
|
||||
result += (radix == 10 ? L'e' : L'^');
|
||||
result += (eout < 0 ? L'-' : L'+');
|
||||
result += radix == 10 ? L'e' : L'^';
|
||||
result += eout < 0 ? L'-' : L'+';
|
||||
eout = abs(eout);
|
||||
wstring expString{};
|
||||
do
|
||||
|
@ -1283,7 +1279,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radi
|
|||
// why a pointer to the rational is passed in.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
wstring RatToString(_Inout_ PRAT& prat, NumberFormat format, uint32_t radix, int32_t precision)
|
||||
wstring RatToString(_Inout_ const PRAT& prat, NumberFormat format, uint32_t radix, int32_t precision)
|
||||
{
|
||||
PNUMBER p = RatToNumber(prat, radix, precision);
|
||||
|
||||
|
@ -1415,7 +1411,7 @@ PNUMBER i32factnum(int32_t ini32, uint32_t radix)
|
|||
mulnum(&lret, tmp, radix);
|
||||
destroynum(tmp);
|
||||
}
|
||||
return (lret);
|
||||
return lret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1439,17 +1435,18 @@ PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix)
|
|||
|
||||
lret = i32tonum(1, radix);
|
||||
|
||||
while (start <= stop)
|
||||
for (; start <= stop; start++)
|
||||
{
|
||||
if (start)
|
||||
if (!start)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = i32tonum(start, radix);
|
||||
mulnum(&lret, tmp, radix);
|
||||
destroynum(tmp);
|
||||
}
|
||||
start++;
|
||||
}
|
||||
return (lret);
|
||||
return lret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1470,7 +1467,7 @@ void numpowi32(_Inout_ PNUMBER* proot, int32_t power, uint32_t radix, int32_t pr
|
|||
{
|
||||
PNUMBER lret = i32tonum(1, radix);
|
||||
|
||||
while (power > 0)
|
||||
for (; power > 0; power >>= 1)
|
||||
{
|
||||
if (power & 1)
|
||||
{
|
||||
|
@ -1478,7 +1475,6 @@ void numpowi32(_Inout_ PNUMBER* proot, int32_t power, uint32_t radix, int32_t pr
|
|||
}
|
||||
mulnum(proot, *proot, radix);
|
||||
TRIMNUM(*proot, precision);
|
||||
power >>= 1;
|
||||
}
|
||||
destroynum(*proot);
|
||||
*proot = lret;
|
||||
|
@ -1503,7 +1499,7 @@ void ratpowi32(_Inout_ PRAT* proot, int32_t power, int32_t precision)
|
|||
if (power < 0)
|
||||
{
|
||||
// Take the positive power and invert answer.
|
||||
PNUMBER pnumtemp = nullptr;
|
||||
PNUMBER pnumtemp;
|
||||
ratpowi32(proot, -power, precision);
|
||||
pnumtemp = (*proot)->pp;
|
||||
(*proot)->pp = (*proot)->pq;
|
||||
|
@ -1511,16 +1507,14 @@ void ratpowi32(_Inout_ PRAT* proot, int32_t power, int32_t precision)
|
|||
}
|
||||
else
|
||||
{
|
||||
PRAT lret = nullptr;
|
||||
|
||||
lret = i32torat(1);
|
||||
PRAT lret = i32torat(1);
|
||||
|
||||
while (power > 0)
|
||||
{
|
||||
if (power & 1)
|
||||
{
|
||||
mulnumx(&(lret->pp), (*proot)->pp);
|
||||
mulnumx(&(lret->pq), (*proot)->pq);
|
||||
mulnumx(&lret->pp, (*proot)->pp);
|
||||
mulnumx(&lret->pq, (*proot)->pq);
|
||||
}
|
||||
mulrat(proot, *proot, precision);
|
||||
trimit(&lret, precision);
|
||||
|
|
|
@ -44,8 +44,8 @@ void _exprat(_Inout_ PRAT* px, int32_t precision)
|
|||
{
|
||||
CREATETAYLOR();
|
||||
|
||||
addnum(&(pret->pp), num_one, BASEX);
|
||||
addnum(&(pret->pq), num_one, BASEX);
|
||||
addnum(&pret->pp, num_one, BASEX);
|
||||
addnum(&pret->pq, num_one, BASEX);
|
||||
DUPRAT(thisterm, pret);
|
||||
|
||||
n2 = i32tonum(0L, BASEX);
|
||||
|
@ -67,7 +67,7 @@ void exprat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
|
|||
if (rat_gt(*px, rat_max_exp, precision) || rat_lt(*px, rat_min_exp, precision))
|
||||
{
|
||||
// Don't attempt exp of anything large.
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
|
||||
DUPRAT(pwr, rat_exp);
|
||||
|
@ -131,7 +131,7 @@ void _lograt(PRAT* px, int32_t precision)
|
|||
|
||||
// sub one from x
|
||||
(*px)->pq->sign *= -1;
|
||||
addnum(&((*px)->pp), (*px)->pq, BASEX);
|
||||
addnum(&(*px)->pp, (*px)->pq, BASEX);
|
||||
(*px)->pq->sign *= -1;
|
||||
|
||||
DUPRAT(pret, *px);
|
||||
|
@ -158,7 +158,7 @@ void lograt(_Inout_ PRAT* px, int32_t precision)
|
|||
// Check for someone taking the log of zero or a negative number.
|
||||
if (rat_le(*px, rat_zero, precision))
|
||||
{
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
|
||||
// Get number > 1, for scaling
|
||||
|
@ -409,7 +409,7 @@ void powratcomp(_Inout_ PRAT* px, _In_ PRAT y, uint32_t radix, int32_t precision
|
|||
// *px is zero.
|
||||
if (rat_lt(y, rat_zero, precision))
|
||||
{
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
else if (zerrat(y))
|
||||
{
|
||||
|
@ -424,7 +424,7 @@ void powratcomp(_Inout_ PRAT* px, _In_ PRAT y, uint32_t radix, int32_t precision
|
|||
PRAT pxint = nullptr;
|
||||
DUPRAT(pxint, *px);
|
||||
subrat(&pxint, rat_one, precision);
|
||||
if (rat_gt(pxint, rat_negsmallest, precision) && rat_lt(pxint, rat_smallest, precision) && (sign == 1))
|
||||
if (rat_gt(pxint, rat_negsmallest, precision) && rat_lt(pxint, rat_smallest, precision) && sign == 1)
|
||||
{
|
||||
// *px is one, special case a 1 return.
|
||||
DUPRAT(*px, rat_one);
|
||||
|
@ -456,7 +456,7 @@ void powratcomp(_Inout_ PRAT* px, _In_ PRAT y, uint32_t radix, int32_t precision
|
|||
destroyrat(iy);
|
||||
destroyrat(pxint);
|
||||
destroyrat(podd);
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
destroyrat(plnx);
|
||||
ratpowi32(px, inty, precision);
|
||||
|
@ -506,7 +506,7 @@ void powratcomp(_Inout_ PRAT* px, _In_ PRAT y, uint32_t radix, int32_t precision
|
|||
|
||||
if (fBadExponent)
|
||||
{
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -139,9 +139,9 @@ void _gamma(PRAT* pn, uint32_t radix, int32_t precision)
|
|||
// WARNING: mixing numbers and rationals here.
|
||||
// for speed and efficiency.
|
||||
INC(count);
|
||||
mulnumx(&(factorial->pp), count);
|
||||
mulnumx(&factorial->pp, count);
|
||||
INC(count)
|
||||
mulnumx(&(factorial->pp), count);
|
||||
mulnumx(&factorial->pp, count);
|
||||
|
||||
divrat(&factorial, a2, precision);
|
||||
|
||||
|
@ -207,11 +207,11 @@ void factrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
|
|||
fracrat(&frac, radix, precision);
|
||||
|
||||
// Check for negative integers and throw an error.
|
||||
if ((zerrat(frac) || (LOGRATRADIX(frac) <= -precision)) && (SIGN(*px) == -1))
|
||||
if ((zerrat(frac) || LOGRATRADIX(frac) <= -precision) && SIGN(*px) == -1)
|
||||
{
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
while (rat_gt(*px, rat_zero, precision) && (LOGRATRADIX(*px) > -precision))
|
||||
while (rat_gt(*px, rat_zero, precision) && LOGRATRADIX(*px) > -precision)
|
||||
{
|
||||
mulrat(&fact, *px, precision);
|
||||
subrat(px, rat_one, precision);
|
||||
|
|
|
@ -86,7 +86,6 @@ void asinanglerat(_Inout_ PRAT* pa, AngleType angletype, uint32_t radix, int32_t
|
|||
void asinrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
|
||||
|
||||
{
|
||||
PRAT pret = nullptr;
|
||||
PRAT phack = nullptr;
|
||||
int32_t sgn = SIGN(*px);
|
||||
|
||||
|
@ -107,12 +106,13 @@ void asinrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
|
|||
destroyrat(phack);
|
||||
if (rat_gt(*px, pt_eight_five, precision))
|
||||
{
|
||||
PRAT pret = nullptr;
|
||||
if (rat_gt(*px, rat_one, precision))
|
||||
{
|
||||
subrat(px, rat_one, precision);
|
||||
if (rat_gt(*px, rat_smallest, precision))
|
||||
{
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -285,14 +285,14 @@ void atanrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
|
|||
(*px)->pp->sign = 1;
|
||||
(*px)->pq->sign = 1;
|
||||
|
||||
if (rat_gt((*px), pt_eight_five, precision))
|
||||
if (rat_gt(*px, pt_eight_five, precision))
|
||||
{
|
||||
if (rat_gt((*px), rat_two, precision))
|
||||
if (rat_gt(*px, rat_two, precision))
|
||||
{
|
||||
(*px)->pp->sign = sgn;
|
||||
(*px)->pq->sign = 1;
|
||||
DUPRAT(tmpx, rat_one);
|
||||
divrat(&tmpx, (*px), precision);
|
||||
divrat(&tmpx, *px, precision);
|
||||
_atanrat(&tmpx, precision);
|
||||
tmpx->pp->sign = sgn;
|
||||
tmpx->pq->sign = 1;
|
||||
|
|
|
@ -29,7 +29,7 @@ void lshrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision)
|
|||
if (rat_gt(b, rat_max_exp, precision))
|
||||
{
|
||||
// Don't attempt lsh of anything big
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
const int32_t intb = rattoi32(b, radix, precision);
|
||||
DUPRAT(pwr, rat_two);
|
||||
|
@ -51,7 +51,7 @@ void rshrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision)
|
|||
if (rat_lt(b, rat_min_exp, precision))
|
||||
{
|
||||
// Don't attempt rsh of anything big and negative.
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
const int32_t intb = rattoi32(b, radix, precision);
|
||||
DUPRAT(pwr, rat_two);
|
||||
|
@ -109,7 +109,7 @@ void boolrat(PRAT* pa, PRAT b, int func, uint32_t radix, int32_t precision)
|
|||
DUPRAT(tmp, b);
|
||||
intrat(&tmp, radix, precision);
|
||||
|
||||
boolnum(&((*pa)->pp), tmp->pp, func);
|
||||
boolnum(&(*pa)->pp, tmp->pp, func);
|
||||
destroyrat(tmp);
|
||||
}
|
||||
|
||||
|
@ -151,8 +151,8 @@ void boolnum(PNUMBER* pa, PNUMBER b, int func)
|
|||
pchc = c->mant;
|
||||
for (; cdigits > 0; cdigits--, mexp++)
|
||||
{
|
||||
da = (((mexp >= a->exp) && (cdigits + a->exp - c->exp > (c->cdigit - a->cdigit))) ? *pcha++ : 0);
|
||||
db = (((mexp >= b->exp) && (cdigits + b->exp - c->exp > (c->cdigit - b->cdigit))) ? *pchb++ : 0);
|
||||
da = mexp >= a->exp && cdigits + a->exp - c->exp > c->cdigit - a->cdigit ? *pcha++ : 0;
|
||||
db = mexp >= b->exp && cdigits + b->exp - c->exp > c->cdigit - b->cdigit ? *pchb++ : 0;
|
||||
switch (func)
|
||||
{
|
||||
case FUNC_AND:
|
||||
|
@ -167,7 +167,7 @@ void boolnum(PNUMBER* pa, PNUMBER b, int func)
|
|||
}
|
||||
}
|
||||
c->sign = a->sign;
|
||||
while (c->cdigit > 1 && *(--pchc) == 0)
|
||||
while (c->cdigit > 1 && *--pchc == 0)
|
||||
{
|
||||
c->cdigit--;
|
||||
}
|
||||
|
@ -200,10 +200,10 @@ void remrat(_Inout_ PRAT* pa, _In_ PRAT b)
|
|||
PRAT tmp = nullptr;
|
||||
DUPRAT(tmp, b);
|
||||
|
||||
mulnumx(&((*pa)->pp), tmp->pq);
|
||||
mulnumx(&(tmp->pp), (*pa)->pq);
|
||||
remnum(&((*pa)->pp), tmp->pp, BASEX);
|
||||
mulnumx(&((*pa)->pq), tmp->pq);
|
||||
mulnumx(&(*pa)->pp, tmp->pq);
|
||||
mulnumx(&tmp->pp, (*pa)->pq);
|
||||
remnum(&(*pa)->pp, tmp->pp, BASEX);
|
||||
mulnumx(&(*pa)->pq, tmp->pq);
|
||||
|
||||
// Get *pa back in the integer over integer form.
|
||||
RENORMALIZE(*pa);
|
||||
|
@ -237,12 +237,12 @@ void modrat(_Inout_ PRAT* pa, _In_ PRAT b)
|
|||
PRAT tmp = nullptr;
|
||||
DUPRAT(tmp, b);
|
||||
|
||||
auto needAdjust = (SIGN(*pa) == -1 ? (SIGN(b) == 1) : (SIGN(b) == -1));
|
||||
const auto needAdjust = SIGN(*pa) == -1 ? SIGN(b) == 1 : SIGN(b) == -1;
|
||||
|
||||
mulnumx(&((*pa)->pp), tmp->pq);
|
||||
mulnumx(&(tmp->pp), (*pa)->pq);
|
||||
remnum(&((*pa)->pp), tmp->pp, BASEX);
|
||||
mulnumx(&((*pa)->pq), tmp->pq);
|
||||
mulnumx(&(*pa)->pp, tmp->pq);
|
||||
mulnumx(&tmp->pp, (*pa)->pq);
|
||||
remnum(&(*pa)->pp, tmp->pp, BASEX);
|
||||
mulnumx(&(*pa)->pq, tmp->pq);
|
||||
|
||||
if (needAdjust && !zerrat(*pa))
|
||||
{
|
||||
|
|
|
@ -72,8 +72,8 @@ void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
|
|||
MANTTYPE da; // da is a single 'digit' after possible padding.
|
||||
MANTTYPE db; // db is a single 'digit' after possible padding.
|
||||
MANTTYPE cy = 0; // cy is the value of a carry after adding two 'digits'
|
||||
int32_t fcompla = 0; // fcompla is a flag to signal a is negative.
|
||||
int32_t fcomplb = 0; // fcomplb is a flag to signal b is negative.
|
||||
bool fcompla = false; // fcompla is a flag to signal a is negative.
|
||||
bool fcomplb = false; // fcomplb is a flag to signal b is negative.
|
||||
|
||||
a = *pa;
|
||||
|
||||
|
@ -93,8 +93,8 @@ void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
|
|||
if (a->sign != b->sign)
|
||||
{
|
||||
cy = 1;
|
||||
fcompla = (a->sign == -1);
|
||||
fcomplb = (b->sign == -1);
|
||||
fcompla = a->sign == -1;
|
||||
fcomplb = b->sign == -1;
|
||||
}
|
||||
|
||||
// Loop over all the digits, real and 0 padded. Here we know a and b are
|
||||
|
@ -102,25 +102,25 @@ void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
|
|||
for (; cdigits > 0; cdigits--, mexp++)
|
||||
{
|
||||
// Get digit from a, taking padding into account.
|
||||
da = (((mexp >= a->exp) && (cdigits + a->exp - c->exp > (c->cdigit - a->cdigit))) ? *pcha++ : 0);
|
||||
da = mexp >= a->exp && cdigits + a->exp - c->exp > c->cdigit - a->cdigit ? *pcha++ : 0;
|
||||
// Get digit from b, taking padding into account.
|
||||
db = (((mexp >= b->exp) && (cdigits + b->exp - c->exp > (c->cdigit - b->cdigit))) ? *pchb++ : 0);
|
||||
db = mexp >= b->exp && cdigits + b->exp - c->exp > c->cdigit - b->cdigit ? *pchb++ : 0;
|
||||
|
||||
// Handle complementing for a and b digit. Might be a better way, but
|
||||
// haven't found it yet.
|
||||
if (fcompla)
|
||||
{
|
||||
da = (MANTTYPE)(radix)-1 - da;
|
||||
da = radix - 1 - da;
|
||||
}
|
||||
if (fcomplb)
|
||||
{
|
||||
db = (MANTTYPE)(radix)-1 - db;
|
||||
db = radix - 1 - db;
|
||||
}
|
||||
|
||||
// Update carry as necessary
|
||||
cy = da + db + cy;
|
||||
*pchc++ = (MANTTYPE)(cy % (MANTTYPE)radix);
|
||||
cy /= (MANTTYPE)radix;
|
||||
*pchc++ = cy % radix;
|
||||
cy /= radix;
|
||||
}
|
||||
|
||||
// Handle carry from last sum as extra digit
|
||||
|
@ -135,9 +135,7 @@ void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
|
|||
{
|
||||
c->sign = a->sign;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cy)
|
||||
else if (cy)
|
||||
{
|
||||
c->sign = 1;
|
||||
}
|
||||
|
@ -149,18 +147,17 @@ void _addnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
|
|||
// slower on average.
|
||||
c->sign = -1;
|
||||
cy = 1;
|
||||
for ((cdigits = c->cdigit), (pchc = c->mant); cdigits > 0; cdigits--)
|
||||
for (cdigits = c->cdigit, pchc = c->mant; cdigits > 0; cdigits--)
|
||||
{
|
||||
cy = (MANTTYPE)radix - (MANTTYPE)1 - *pchc + cy;
|
||||
*pchc++ = (MANTTYPE)(cy % (MANTTYPE)radix);
|
||||
cy /= (MANTTYPE)radix;
|
||||
}
|
||||
cy = radix - 1 - *pchc + cy;
|
||||
*pchc++ = cy % radix;
|
||||
cy /= radix;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove leading zeros, remember digits are in order of
|
||||
// increasing significance. i.e. 100 would be 0,0,1
|
||||
while (c->cdigit > 1 && *(--pchc) == 0)
|
||||
while (c->cdigit > 1 && *--pchc == 0)
|
||||
{
|
||||
c->cdigit--;
|
||||
}
|
||||
|
@ -247,7 +244,7 @@ void _mulnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
|
|||
for (ibdigit = b->cdigit; ibdigit > 0; ibdigit--)
|
||||
{
|
||||
cy = 0;
|
||||
mcy = (TWO_MANTTYPE)da * *pchb;
|
||||
mcy = static_cast<TWO_MANTTYPE>(da) * *pchb;
|
||||
if (mcy)
|
||||
{
|
||||
icdigit = 0;
|
||||
|
@ -260,14 +257,14 @@ void _mulnum(PNUMBER* pa, PNUMBER b, uint32_t radix)
|
|||
while (mcy || cy)
|
||||
{
|
||||
// update carry from addition(s) and multiply.
|
||||
cy += (TWO_MANTTYPE)pchc[icdigit] + (mcy % (TWO_MANTTYPE)radix);
|
||||
cy += static_cast<TWO_MANTTYPE>(pchc[icdigit]) + mcy % static_cast<TWO_MANTTYPE>(radix);
|
||||
|
||||
// update result digit from
|
||||
pchc[icdigit++] = (MANTTYPE)(cy % (TWO_MANTTYPE)radix);
|
||||
pchc[icdigit++] = static_cast<MANTTYPE>(cy % static_cast<TWO_MANTTYPE>(radix));
|
||||
|
||||
// update carries from
|
||||
mcy /= (TWO_MANTTYPE)radix;
|
||||
cy /= (TWO_MANTTYPE)radix;
|
||||
mcy /= static_cast<TWO_MANTTYPE>(radix);
|
||||
cy /= static_cast<TWO_MANTTYPE>(radix);
|
||||
}
|
||||
|
||||
pchb++;
|
||||
|
@ -340,7 +337,7 @@ void remnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix)
|
|||
}
|
||||
|
||||
// Subtract the working remainder from the remainder holder.
|
||||
tmp->sign = -1 * (*pa)->sign;
|
||||
tmp->sign = -(*pa)->sign;
|
||||
addnum(pa, tmp, radix);
|
||||
|
||||
destroynum(tmp);
|
||||
|
@ -394,7 +391,7 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
|
|||
|
||||
PNUMBER c = nullptr;
|
||||
createnum(c, thismax + 1);
|
||||
c->exp = (a->cdigit + a->exp) - (b->cdigit + b->exp) + 1;
|
||||
c->exp = a->cdigit + a->exp - (b->cdigit + b->exp) + 1;
|
||||
c->sign = a->sign * b->sign;
|
||||
|
||||
MANTTYPE* ptrc = c->mant + thismax;
|
||||
|
@ -408,7 +405,7 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
|
|||
// Build a table of multiplications of the divisor, this is quicker for
|
||||
// more than radix 'digits'
|
||||
list<PNUMBER> numberList{ i32tonum(0L, radix) };
|
||||
for (uint32_t i = 1; i < radix; i++)
|
||||
for (auto i = radix; i > 1; i--)
|
||||
{
|
||||
PNUMBER newValue = nullptr;
|
||||
DUPNUM(newValue, numberList.front());
|
||||
|
@ -419,8 +416,8 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
|
|||
destroynum(tmp);
|
||||
|
||||
int32_t digit;
|
||||
int32_t cdigits = 0;
|
||||
while (cdigits++ < thismax && !zernum(rem))
|
||||
int32_t cdigits;
|
||||
for (cdigits = 0; cdigits < thismax && !zernum(rem); cdigits++)
|
||||
{
|
||||
digit = radix - 1;
|
||||
PNUMBER multiple = nullptr;
|
||||
|
@ -440,13 +437,12 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
|
|||
multiple->sign *= -1;
|
||||
}
|
||||
rem->exp++;
|
||||
*ptrc-- = (MANTTYPE)digit;
|
||||
*ptrc-- = static_cast<MANTTYPE>(digit);
|
||||
}
|
||||
cdigits--;
|
||||
|
||||
if (c->mant != ++ptrc)
|
||||
{
|
||||
memmove(c->mant, ptrc, (int)(cdigits * sizeof(MANTTYPE)));
|
||||
memmove(c->mant, ptrc, cdigits * sizeof(MANTTYPE));
|
||||
}
|
||||
|
||||
// Cleanup table structure
|
||||
|
@ -491,7 +487,6 @@ void _divnum(PNUMBER* pa, PNUMBER b, uint32_t radix, int32_t precision)
|
|||
bool equnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
||||
|
||||
{
|
||||
int32_t diff;
|
||||
MANTTYPE* pa;
|
||||
MANTTYPE* pb;
|
||||
int32_t cdigits;
|
||||
|
@ -499,26 +494,17 @@ bool equnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
|||
MANTTYPE da;
|
||||
MANTTYPE db;
|
||||
|
||||
diff = (a->cdigit + a->exp) - (b->cdigit + b->exp);
|
||||
if (diff < 0)
|
||||
if (a->cdigit + a->exp != b->cdigit + b->exp)
|
||||
{
|
||||
// If the exponents are different, these are different numbers.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (diff > 0)
|
||||
{
|
||||
// If the exponents are different, these are different numbers.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// OK the exponents match.
|
||||
pa = a->mant;
|
||||
pb = b->mant;
|
||||
pa += a->cdigit - 1;
|
||||
pb += b->cdigit - 1;
|
||||
pa = pa + a->cdigit - 1;
|
||||
pb = pb + b->cdigit - 1;
|
||||
cdigits = max(a->cdigit, b->cdigit);
|
||||
ccdigits = cdigits;
|
||||
|
||||
|
@ -526,8 +512,8 @@ bool equnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
|||
// difference in the digits.
|
||||
for (; cdigits > 0; cdigits--)
|
||||
{
|
||||
da = ((cdigits > (ccdigits - a->cdigit)) ? *pa-- : 0);
|
||||
db = ((cdigits > (ccdigits - b->cdigit)) ? *pb-- : 0);
|
||||
da = cdigits > ccdigits - a->cdigit ? *pa-- : 0;
|
||||
db = cdigits > ccdigits - b->cdigit ? *pb-- : 0;
|
||||
if (da != db)
|
||||
{
|
||||
return false;
|
||||
|
@ -536,8 +522,6 @@ bool equnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
|||
|
||||
// In this case, they are equal.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -557,7 +541,8 @@ bool equnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
|||
bool lessnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
||||
|
||||
{
|
||||
int32_t diff = (a->cdigit + a->exp) - (b->cdigit + b->exp);
|
||||
int32_t diff = a->cdigit + a->exp - (b->cdigit + b->exp);
|
||||
|
||||
if (diff < 0)
|
||||
{
|
||||
// The exponent of a is less than b
|
||||
|
@ -567,20 +552,22 @@ bool lessnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
MANTTYPE* pa = a->mant;
|
||||
MANTTYPE* pb = b->mant;
|
||||
pa += a->cdigit - 1;
|
||||
pb += b->cdigit - 1;
|
||||
int32_t cdigits = max(a->cdigit, b->cdigit);
|
||||
int32_t ccdigits = cdigits;
|
||||
for (; cdigits > 0; cdigits--)
|
||||
|
||||
MANTTYPE* pa = a->mant + a->cdigit - 1;
|
||||
MANTTYPE* pb = b->mant + b->cdigit - 1;
|
||||
auto cdigits = max(a->cdigit, b->cdigit);
|
||||
for (auto ccdigits = cdigits; ccdigits > 0; ccdigits--)
|
||||
{
|
||||
MANTTYPE da = ((cdigits > (ccdigits - a->cdigit)) ? *pa-- : 0);
|
||||
MANTTYPE db = ((cdigits > (ccdigits - b->cdigit)) ? *pb-- : 0);
|
||||
MANTTYPE da = ccdigits > cdigits - a->cdigit ? *pa-- : 0;
|
||||
MANTTYPE db = ccdigits > cdigits - b->cdigit ? *pb-- : 0;
|
||||
diff = da - db;
|
||||
if (diff)
|
||||
if (diff < 0)
|
||||
{
|
||||
return (diff < 0);
|
||||
return true;
|
||||
}
|
||||
if (diff > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// In this case, they are equal.
|
||||
|
@ -602,20 +589,19 @@ bool lessnum(_In_ PNUMBER a, _In_ PNUMBER b)
|
|||
bool zernum(_In_ PNUMBER a)
|
||||
|
||||
{
|
||||
int32_t length;
|
||||
MANTTYPE* pcha;
|
||||
length = a->cdigit;
|
||||
pcha = a->mant;
|
||||
MANTTYPE* pcha = a->mant;
|
||||
|
||||
// loop over all the digits until you find a nonzero or until you run
|
||||
// out of digits
|
||||
while (length-- > 0)
|
||||
for (auto length = a->cdigit; length > 0; length--)
|
||||
{
|
||||
if (*pcha++)
|
||||
if (*pcha)
|
||||
{
|
||||
// One of the digits isn't zero, therefore the number isn't zero
|
||||
return false;
|
||||
}
|
||||
|
||||
++pcha;
|
||||
}
|
||||
// All of the digits are zero, therefore the number is zero
|
||||
return true;
|
||||
|
|
|
@ -40,16 +40,13 @@ using namespace std;
|
|||
void gcdrat(_Inout_ PRAT* pa, int32_t precision)
|
||||
|
||||
{
|
||||
PNUMBER pgcd = nullptr;
|
||||
PRAT a = nullptr;
|
||||
|
||||
a = *pa;
|
||||
pgcd = gcd(a->pp, a->pq);
|
||||
PRAT a = *pa;
|
||||
PNUMBER pgcd = gcd(a->pp, a->pq);
|
||||
|
||||
if (!zernum(pgcd))
|
||||
{
|
||||
divnumx(&(a->pp), pgcd, precision);
|
||||
divnumx(&(a->pq), pgcd, precision);
|
||||
divnumx(&a->pp, pgcd, precision);
|
||||
divnumx(&a->pq, pgcd, precision);
|
||||
}
|
||||
|
||||
destroynum(pgcd);
|
||||
|
@ -79,7 +76,7 @@ void fracrat(_Inout_ PRAT* pa, uint32_t radix, int32_t precision)
|
|||
flatrat(*pa, radix, precision);
|
||||
}
|
||||
|
||||
remnum(&((*pa)->pp), (*pa)->pq, BASEX);
|
||||
remnum(&(*pa)->pp, (*pa)->pq, BASEX);
|
||||
|
||||
// Get *pa back in the integer over integer form.
|
||||
RENORMALIZE(*pa);
|
||||
|
@ -104,8 +101,8 @@ void mulrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
|
|||
// Only do the multiply if it isn't zero.
|
||||
if (!zernum((*pa)->pp))
|
||||
{
|
||||
mulnumx(&((*pa)->pp), b->pp);
|
||||
mulnumx(&((*pa)->pq), b->pq);
|
||||
mulnumx(&(*pa)->pp, b->pp);
|
||||
mulnumx(&(*pa)->pq, b->pq);
|
||||
trimit(pa, precision);
|
||||
}
|
||||
else
|
||||
|
@ -138,13 +135,13 @@ void divrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
|
|||
if (!zernum((*pa)->pp))
|
||||
{
|
||||
// Only do the divide if the top isn't zero.
|
||||
mulnumx(&((*pa)->pp), b->pq);
|
||||
mulnumx(&((*pa)->pq), b->pp);
|
||||
mulnumx(&(*pa)->pp, b->pq);
|
||||
mulnumx(&(*pa)->pq, b->pp);
|
||||
|
||||
if (zernum((*pa)->pq))
|
||||
{
|
||||
// raise an exception if the bottom is 0.
|
||||
throw(CALC_E_DIVIDEBYZERO);
|
||||
throw CALC_E_DIVIDEBYZERO;
|
||||
}
|
||||
trimit(pa, precision);
|
||||
}
|
||||
|
@ -155,7 +152,7 @@ void divrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
|
|||
{
|
||||
// If bottom is zero
|
||||
// 0 / 0 is indefinite, raise an exception.
|
||||
throw(CALC_E_INDEFINITE);
|
||||
throw CALC_E_INDEFINITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -218,16 +215,16 @@ void addrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision)
|
|||
(*pa)->pq->sign = 1;
|
||||
b->pp->sign *= b->pq->sign;
|
||||
b->pq->sign = 1;
|
||||
addnum(&((*pa)->pp), b->pp, BASEX);
|
||||
addnum(&(*pa)->pp, b->pp, BASEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Usual case q's aren't the same.
|
||||
DUPNUM(bot, (*pa)->pq);
|
||||
mulnumx(&bot, b->pq);
|
||||
mulnumx(&((*pa)->pp), b->pq);
|
||||
mulnumx(&((*pa)->pq), b->pp);
|
||||
addnum(&((*pa)->pp), (*pa)->pq, BASEX);
|
||||
mulnumx(&(*pa)->pp, b->pq);
|
||||
mulnumx(&(*pa)->pq, b->pp);
|
||||
addnum(&(*pa)->pp, (*pa)->pq, BASEX);
|
||||
destroynum((*pa)->pq);
|
||||
(*pa)->pq = bot;
|
||||
trimit(pa, precision);
|
||||
|
@ -283,5 +280,5 @@ void rootrat(_Inout_ PRAT* py, _In_ PRAT n, uint32_t radix, int32_t precision)
|
|||
bool zerrat(_In_ PRAT a)
|
||||
|
||||
{
|
||||
return (zernum(a->pp));
|
||||
return zernum(a->pp);
|
||||
}
|
||||
|
|
|
@ -339,7 +339,7 @@ extern bool zerrat(_In_ PRAT a); // returns true if a == 0/q
|
|||
extern std::wstring NumberToString(_Inout_ PNUMBER& pnum, NumberFormat format, uint32_t radix, int32_t precision);
|
||||
|
||||
// returns a text representation of a PRAT
|
||||
extern std::wstring RatToString(_Inout_ PRAT& prat, NumberFormat format, uint32_t radix, int32_t precision);
|
||||
extern std::wstring RatToString(_Inout_ const PRAT& prat, NumberFormat format, uint32_t radix, int32_t precision);
|
||||
// converts a PRAT into a PNUMBER
|
||||
extern PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision);
|
||||
// flattens a PRAT by converting it to a PNUMBER and back to a PRAT
|
||||
|
@ -367,7 +367,7 @@ extern PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix);
|
|||
extern PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix);
|
||||
|
||||
// creates a empty/undefined rational representation (p/q)
|
||||
extern PRAT _createrat(void);
|
||||
extern PRAT _createrat();
|
||||
|
||||
// returns a new rat structure with the acos of x->p/x->q taking into account
|
||||
// angle type
|
||||
|
@ -439,7 +439,7 @@ extern void tanrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|||
// angle type
|
||||
extern void tananglerat(_Inout_ PRAT* px, AngleType angletype, uint32_t radix, int32_t precision);
|
||||
|
||||
extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src);
|
||||
extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* src);
|
||||
|
||||
extern void _destroynum(_Frees_ptr_opt_ PNUMBER pnum);
|
||||
extern void _destroyrat(_Frees_ptr_opt_ PRAT prat);
|
||||
|
@ -480,6 +480,6 @@ extern bool rat_ge(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
|||
extern bool rat_lt(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
||||
extern bool rat_le(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
||||
extern void inbetween(_In_ PRAT* px, _In_ PRAT range, int32_t precision);
|
||||
extern void trimit(_Inout_ PRAT* px, int32_t precision);
|
||||
extern void trimit(_Inout_ const PRAT* px, int32_t precision);
|
||||
extern void _dumprawrat(_In_ const wchar_t* varname, _In_ PRAT rat, std::wostream& out);
|
||||
extern void _dumprawnum(_In_ const wchar_t* varname, _In_ PNUMBER num, std::wostream& out);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
void _readconstants(void);
|
||||
void _readconstants();
|
||||
|
||||
#if defined(GEN_CONST)
|
||||
static int cbitsofprecision = 0;
|
||||
|
@ -136,19 +136,20 @@ void ChangeConstants(uint32_t radix, int32_t precision)
|
|||
// in the internal BASEX radix, this is important for length calculations
|
||||
// in translating from radix to BASEX and back.
|
||||
|
||||
uint64_t limit = static_cast<uint64_t>(BASEX) / static_cast<uint64_t>(radix);
|
||||
const uint32_t limit = BASEX / radix;
|
||||
g_ratio = 0;
|
||||
for (uint32_t digit = 1; digit < limit; digit *= radix)
|
||||
{
|
||||
g_ratio++;
|
||||
}
|
||||
g_ratio += !g_ratio;
|
||||
if (g_ratio == 0)
|
||||
g_ratio = 1; // g_ratio is always at least 1
|
||||
|
||||
destroyrat(rat_nRadix);
|
||||
rat_nRadix = i32torat(radix);
|
||||
|
||||
// Check to see what we have to recalculate and what we don't
|
||||
if (cbitsofprecision < (g_ratio * static_cast<int32_t>(radix) * precision))
|
||||
if (cbitsofprecision < g_ratio * static_cast<int32_t>(radix) * precision)
|
||||
{
|
||||
g_ftrueinfinite = false;
|
||||
|
||||
|
@ -202,17 +203,17 @@ void ChangeConstants(uint32_t radix, int32_t precision)
|
|||
}
|
||||
|
||||
DUPRAT(rat_qword, rat_two);
|
||||
numpowi32(&(rat_qword->pp), 64, BASEX, precision);
|
||||
numpowi32(&rat_qword->pp, 64, BASEX, precision);
|
||||
subrat(&rat_qword, rat_one, precision);
|
||||
DUMPRAWRAT(rat_qword);
|
||||
|
||||
DUPRAT(rat_dword, rat_two);
|
||||
numpowi32(&(rat_dword->pp), 32, BASEX, precision);
|
||||
numpowi32(&rat_dword->pp, 32, BASEX, precision);
|
||||
subrat(&rat_dword, rat_one, precision);
|
||||
DUMPRAWRAT(rat_dword);
|
||||
|
||||
DUPRAT(rat_max_i32, rat_two);
|
||||
numpowi32(&(rat_max_i32->pp), 31, BASEX, precision);
|
||||
numpowi32(&rat_max_i32->pp, 31, BASEX, precision);
|
||||
DUPRAT(rat_min_i32, rat_max_i32);
|
||||
subrat(&rat_max_i32, rat_one, precision); // rat_max_i32 = 2^31 -1
|
||||
DUMPRAWRAT(rat_max_i32);
|
||||
|
@ -337,7 +338,7 @@ bool rat_equ(_In_ PRAT a, _In_ PRAT b, int32_t precision)
|
|||
addrat(&rattmp, b, precision);
|
||||
bool bret = zernum(rattmp->pp);
|
||||
destroyrat(rattmp);
|
||||
return (bret);
|
||||
return bret;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -359,9 +360,9 @@ bool rat_ge(_In_ PRAT a, _In_ PRAT b, int32_t precision)
|
|||
b->pp->sign *= -1;
|
||||
addrat(&rattmp, b, precision);
|
||||
b->pp->sign *= -1;
|
||||
bool bret = (zernum(rattmp->pp) || SIGN(rattmp) == 1);
|
||||
bool bret = zernum(rattmp->pp) || SIGN(rattmp) == 1;
|
||||
destroyrat(rattmp);
|
||||
return (bret);
|
||||
return bret;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -383,9 +384,9 @@ bool rat_gt(_In_ PRAT a, _In_ PRAT b, int32_t precision)
|
|||
b->pp->sign *= -1;
|
||||
addrat(&rattmp, b, precision);
|
||||
b->pp->sign *= -1;
|
||||
bool bret = (!zernum(rattmp->pp) && SIGN(rattmp) == 1);
|
||||
bool bret = !zernum(rattmp->pp) && SIGN(rattmp) == 1;
|
||||
destroyrat(rattmp);
|
||||
return (bret);
|
||||
return bret;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -407,9 +408,9 @@ bool rat_le(_In_ PRAT a, _In_ PRAT b, int32_t precision)
|
|||
b->pp->sign *= -1;
|
||||
addrat(&rattmp, b, precision);
|
||||
b->pp->sign *= -1;
|
||||
bool bret = (zernum(rattmp->pp) || SIGN(rattmp) == -1);
|
||||
bool bret = zernum(rattmp->pp) || SIGN(rattmp) == -1;
|
||||
destroyrat(rattmp);
|
||||
return (bret);
|
||||
return bret;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -431,9 +432,9 @@ bool rat_lt(_In_ PRAT a, _In_ PRAT b, int32_t precision)
|
|||
b->pp->sign *= -1;
|
||||
addrat(&rattmp, b, precision);
|
||||
b->pp->sign *= -1;
|
||||
bool bret = (!zernum(rattmp->pp) && SIGN(rattmp) == -1);
|
||||
bool bret = !zernum(rattmp->pp) && SIGN(rattmp) == -1;
|
||||
destroyrat(rattmp);
|
||||
return (bret);
|
||||
return bret;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -454,9 +455,9 @@ bool rat_neq(_In_ PRAT a, _In_ PRAT b, int32_t precision)
|
|||
DUPRAT(rattmp, a);
|
||||
rattmp->pp->sign *= -1;
|
||||
addrat(&rattmp, b, precision);
|
||||
bool bret = !(zernum(rattmp->pp));
|
||||
bool bret = !zernum(rattmp->pp);
|
||||
destroyrat(rattmp);
|
||||
return (bret);
|
||||
return bret;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -477,7 +478,7 @@ void scale(_Inout_ PRAT* px, _In_ PRAT scalefact, uint32_t radix, int32_t precis
|
|||
|
||||
// Logscale is a quick way to tell how much extra precision is needed for
|
||||
// scaling by scalefact.
|
||||
int32_t logscale = g_ratio * ((pret->pp->cdigit + pret->pp->exp) - (pret->pq->cdigit + pret->pq->exp));
|
||||
int32_t logscale = g_ratio * (pret->pp->cdigit + pret->pp->exp - (pret->pq->cdigit + pret->pq->exp));
|
||||
if (logscale > 0)
|
||||
{
|
||||
precision += logscale;
|
||||
|
@ -511,7 +512,7 @@ void scale2pi(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
|
|||
|
||||
// Logscale is a quick way to tell how much extra precision is needed for
|
||||
// scaling by 2 pi.
|
||||
int32_t logscale = g_ratio * ((pret->pp->cdigit + pret->pp->exp) - (pret->pq->cdigit + pret->pq->exp));
|
||||
int32_t logscale = g_ratio * (pret->pp->cdigit + pret->pp->exp - (pret->pq->cdigit + pret->pq->exp));
|
||||
if (logscale > 0)
|
||||
{
|
||||
precision += logscale;
|
||||
|
@ -610,7 +611,7 @@ void _dumprawnum(_In_ const wchar_t* varname, _In_ PNUMBER num, wostream& out)
|
|||
out << L"};\n";
|
||||
}
|
||||
|
||||
void _readconstants(void)
|
||||
void _readconstants()
|
||||
|
||||
{
|
||||
READRAWNUM(num_one);
|
||||
|
@ -674,14 +675,14 @@ void _readconstants(void)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void trimit(_Inout_ PRAT* px, int32_t precision)
|
||||
void trimit(_Inout_ const PRAT* px, int32_t precision)
|
||||
|
||||
{
|
||||
if (!g_ftrueinfinite)
|
||||
{
|
||||
PNUMBER pp = (*px)->pp;
|
||||
PNUMBER pq = (*px)->pq;
|
||||
int32_t trim = g_ratio * (min((pp->cdigit + pp->exp), (pq->cdigit + pq->exp)) - 1) - precision;
|
||||
int32_t trim = g_ratio * (min(pp->cdigit + pp->exp, pq->cdigit + pq->exp) - 1) - precision;
|
||||
if (trim > g_ratio)
|
||||
{
|
||||
trim /= g_ratio;
|
||||
|
@ -692,7 +693,7 @@ void trimit(_Inout_ PRAT* px, int32_t precision)
|
|||
}
|
||||
else
|
||||
{
|
||||
memmove(pp->mant, &(pp->mant[trim - pp->exp]), sizeof(MANTTYPE) * (pp->cdigit - trim + pp->exp));
|
||||
memmove(pp->mant, &pp->mant[trim - pp->exp], sizeof(MANTTYPE) * (pp->cdigit - trim + pp->exp));
|
||||
pp->cdigit -= trim - pp->exp;
|
||||
pp->exp = 0;
|
||||
}
|
||||
|
@ -703,7 +704,7 @@ void trimit(_Inout_ PRAT* px, int32_t precision)
|
|||
}
|
||||
else
|
||||
{
|
||||
memmove(pq->mant, &(pq->mant[trim - pq->exp]), sizeof(MANTTYPE) * (pq->cdigit - trim + pq->exp));
|
||||
memmove(pq->mant, &pq->mant[trim - pq->exp], sizeof(MANTTYPE) * (pq->cdigit - trim + pq->exp));
|
||||
pq->cdigit -= trim - pq->exp;
|
||||
pq->exp = 0;
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ void _tanrat(PRAT* px, uint32_t radix, int32_t precision)
|
|||
if (zerrat(ptmp))
|
||||
{
|
||||
destroyrat(ptmp);
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
divrat(px, ptmp, precision);
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ void _sinhrat(PRAT* px, int32_t precision)
|
|||
if (!IsValidForHypFunc(*px, precision))
|
||||
{
|
||||
// Don't attempt exp of anything large or small
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
|
||||
CREATETAYLOR();
|
||||
|
@ -149,7 +149,7 @@ void _coshrat(PRAT* px, uint32_t radix, int32_t precision)
|
|||
if (!IsValidForHypFunc(*px, precision))
|
||||
{
|
||||
// Don't attempt exp of anything large or small
|
||||
throw(CALC_E_DOMAIN);
|
||||
throw CALC_E_DOMAIN;
|
||||
}
|
||||
|
||||
CREATETAYLOR();
|
||||
|
@ -219,8 +219,8 @@ void tanhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
|
|||
DUPRAT(ptmp, *px);
|
||||
sinhrat(px, radix, precision);
|
||||
coshrat(&ptmp, radix, precision);
|
||||
mulnumx(&((*px)->pp), ptmp->pq);
|
||||
mulnumx(&((*px)->pq), ptmp->pp);
|
||||
mulnumx(&(*px)->pp, ptmp->pq);
|
||||
mulnumx(&(*px)->pq, ptmp->pp);
|
||||
|
||||
destroyrat(ptmp);
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ static constexpr uint32_t OPTIMALDIGITSALLOWED = 7U;
|
|||
static constexpr wchar_t LEFTESCAPECHAR = L'{';
|
||||
static constexpr wchar_t RIGHTESCAPECHAR = L'}';
|
||||
|
||||
static const double OPTIMALDECIMALALLOWED = 1e-6; // pow(10, -1 * (OPTIMALDIGITSALLOWED - 1));
|
||||
static const double MINIMUMDECIMALALLOWED = 1e-14; // pow(10, -1 * (MAXIMUMDIGITSALLOWED - 1));
|
||||
static constexpr double OPTIMALDECIMALALLOWED = 1e-6; // pow(10, -1 * (OPTIMALDIGITSALLOWED - 1));
|
||||
static constexpr double MINIMUMDECIMALALLOWED = 1e-14; // pow(10, -1 * (MAXIMUMDIGITSALLOWED - 1));
|
||||
|
||||
unordered_map<wchar_t, wstring> quoteConversions;
|
||||
unordered_map<wstring, wchar_t> unquoteConversions;
|
||||
|
@ -65,8 +65,8 @@ UnitConverter::UnitConverter(_In_ const shared_ptr<IConverterDataLoader>& dataLo
|
|||
unquoteConversions[L"{sc}"] = L';';
|
||||
unquoteConversions[L"{lb}"] = LEFTESCAPECHAR;
|
||||
unquoteConversions[L"{rb}"] = RIGHTESCAPECHAR;
|
||||
ClearValues();
|
||||
ResetCategoriesAndRatios();
|
||||
UnitConverter::ClearValues();
|
||||
UnitConverter::ResetCategoriesAndRatios();
|
||||
}
|
||||
|
||||
void UnitConverter::Initialize()
|
||||
|
@ -76,10 +76,12 @@ void UnitConverter::Initialize()
|
|||
|
||||
bool UnitConverter::CheckLoad()
|
||||
{
|
||||
if (m_categories.empty())
|
||||
if (!m_categories.empty())
|
||||
{
|
||||
ResetCategoriesAndRatios();
|
||||
return true;
|
||||
}
|
||||
|
||||
ResetCategoriesAndRatios();
|
||||
return !m_categories.empty();
|
||||
}
|
||||
|
||||
|
@ -111,8 +113,8 @@ CategorySelectionInitializer UnitConverter::SetCurrentCategory(const Category& i
|
|||
{
|
||||
for (auto& unit : m_categoryToUnits[m_currentCategory.id])
|
||||
{
|
||||
unit.isConversionSource = (unit.id == m_fromType.id);
|
||||
unit.isConversionTarget = (unit.id == m_toType.id);
|
||||
unit.isConversionSource = unit.id == m_fromType.id;
|
||||
unit.isConversionTarget = unit.id == m_toType.id;
|
||||
}
|
||||
m_currentCategory = input;
|
||||
if (!m_currentCategory.supportsNegative && m_currentDisplay.front() == L'-')
|
||||
|
@ -184,7 +186,7 @@ void UnitConverter::SwitchActive(const wstring& newValue)
|
|||
swap(m_currentHasDecimal, m_returnHasDecimal);
|
||||
m_returnDisplay = m_currentDisplay;
|
||||
m_currentDisplay = newValue;
|
||||
m_currentHasDecimal = (m_currentDisplay.find(L'.') != wstring::npos);
|
||||
m_currentHasDecimal = m_currentDisplay.find(L'.') != wstring::npos;
|
||||
m_switchedActive = true;
|
||||
|
||||
if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr)
|
||||
|
@ -196,12 +198,12 @@ void UnitConverter::SwitchActive(const wstring& newValue)
|
|||
}
|
||||
}
|
||||
|
||||
bool UnitConversionManager::UnitConverter::IsSwitchedActive() const
|
||||
bool UnitConverter::IsSwitchedActive() const
|
||||
{
|
||||
return m_switchedActive;
|
||||
}
|
||||
|
||||
wstring UnitConverter::CategoryToString(const Category& c, wstring_view delimiter)
|
||||
wstring UnitConverter::CategoryToString(const Category& c, wstring_view delimiter) const
|
||||
{
|
||||
return Quote(std::to_wstring(c.id))
|
||||
.append(delimiter)
|
||||
|
@ -229,7 +231,7 @@ vector<wstring> UnitConverter::StringToVector(wstring_view w, wstring_view delim
|
|||
}
|
||||
return serializedTokens;
|
||||
}
|
||||
wstring UnitConverter::UnitToString(const Unit& u, wstring_view delimiter)
|
||||
wstring UnitConverter::UnitToString(const Unit& u, wstring_view delimiter) const
|
||||
{
|
||||
return Quote(std::to_wstring(u.id))
|
||||
.append(delimiter)
|
||||
|
@ -247,26 +249,26 @@ wstring UnitConverter::UnitToString(const Unit& u, wstring_view delimiter)
|
|||
|
||||
Unit UnitConverter::StringToUnit(wstring_view w)
|
||||
{
|
||||
vector<wstring> tokenList = StringToVector(w, L";");
|
||||
const vector<wstring> tokenList = StringToVector(w, L";");
|
||||
assert(tokenList.size() == EXPECTEDSERIALIZEDUNITTOKENCOUNT);
|
||||
Unit serializedUnit;
|
||||
serializedUnit.id = wcstol(Unquote(tokenList[0]).c_str(), nullptr, 10);
|
||||
serializedUnit.name = Unquote(tokenList[1]);
|
||||
serializedUnit.accessibleName = serializedUnit.name;
|
||||
serializedUnit.abbreviation = Unquote(tokenList[2]);
|
||||
serializedUnit.isConversionSource = (tokenList[3] == L"1");
|
||||
serializedUnit.isConversionTarget = (tokenList[4] == L"1");
|
||||
serializedUnit.isWhimsical = (tokenList[5] == L"1");
|
||||
serializedUnit.isConversionSource = tokenList[3] == L"1";
|
||||
serializedUnit.isConversionTarget = tokenList[4] == L"1";
|
||||
serializedUnit.isWhimsical = tokenList[5] == L"1";
|
||||
return serializedUnit;
|
||||
}
|
||||
|
||||
Category UnitConverter::StringToCategory(wstring_view w)
|
||||
{
|
||||
vector<wstring> tokenList = StringToVector(w, L";");
|
||||
const vector<wstring> tokenList = StringToVector(w, L";");
|
||||
assert(tokenList.size() == EXPECTEDSERIALIZEDCATEGORYTOKENCOUNT);
|
||||
Category serializedCategory;
|
||||
serializedCategory.id = wcstol(Unquote(tokenList[0]).c_str(), nullptr, 10);
|
||||
serializedCategory.supportsNegative = (tokenList[1] == L"1");
|
||||
serializedCategory.supportsNegative = tokenList[1] == L"1";
|
||||
serializedCategory.name = Unquote(tokenList[2]);
|
||||
return serializedCategory;
|
||||
}
|
||||
|
@ -282,18 +284,18 @@ void UnitConverter::RestoreUserPreferences(wstring_view userPreferences)
|
|||
return;
|
||||
}
|
||||
|
||||
vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
|
||||
const vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
|
||||
if (outerTokens.size() != 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto fromType = StringToUnit(outerTokens[0]);
|
||||
auto toType = StringToUnit(outerTokens[1]);
|
||||
const auto fromType = StringToUnit(outerTokens[0]);
|
||||
const auto toType = StringToUnit(outerTokens[1]);
|
||||
m_currentCategory = StringToCategory(outerTokens[2]);
|
||||
|
||||
// Only restore from the saved units if they are valid in the current available units.
|
||||
auto itr = m_categoryToUnits.find(m_currentCategory.id);
|
||||
const auto itr = m_categoryToUnits.find(m_currentCategory.id);
|
||||
if (itr != m_categoryToUnits.end())
|
||||
{
|
||||
const auto& curUnits = itr->second;
|
||||
|
@ -398,8 +400,8 @@ void UnitConverter::SendCommand(Command command)
|
|||
}
|
||||
|
||||
// TODO: Localization of characters
|
||||
bool clearFront = false;
|
||||
bool clearBack = false;
|
||||
bool clearFront;
|
||||
bool clearBack;
|
||||
if (command != Command::Negate && m_switchedActive)
|
||||
{
|
||||
ClearValues();
|
||||
|
@ -409,10 +411,10 @@ void UnitConverter::SendCommand(Command command)
|
|||
}
|
||||
else
|
||||
{
|
||||
clearFront = (m_currentDisplay == L"0");
|
||||
clearFront = m_currentDisplay == L"0";
|
||||
clearBack =
|
||||
((m_currentHasDecimal && m_currentDisplay.size() - 1 >= MAXIMUMDIGITSALLOWED)
|
||||
|| (!m_currentHasDecimal && m_currentDisplay.size() >= MAXIMUMDIGITSALLOWED));
|
||||
m_currentHasDecimal && m_currentDisplay.size() - 1 >= MAXIMUMDIGITSALLOWED
|
||||
|| !m_currentHasDecimal && m_currentDisplay.size() >= MAXIMUMDIGITSALLOWED;
|
||||
}
|
||||
|
||||
switch (command)
|
||||
|
@ -470,7 +472,7 @@ void UnitConverter::SendCommand(Command command)
|
|||
case Command::Backspace:
|
||||
clearFront = false;
|
||||
clearBack = false;
|
||||
if ((m_currentDisplay.front() != L'-' && m_currentDisplay.size() > 1) || m_currentDisplay.size() > 2)
|
||||
if (m_currentDisplay.front() != L'-' && m_currentDisplay.size() > 1 || m_currentDisplay.size() > 2)
|
||||
{
|
||||
if (m_currentDisplay.back() == L'.')
|
||||
{
|
||||
|
@ -514,6 +516,7 @@ void UnitConverter::SendCommand(Command command)
|
|||
ResetCategoriesAndRatios();
|
||||
break;
|
||||
|
||||
case Command::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -548,7 +551,7 @@ void UnitConverter::SetViewModelCurrencyCallback(_In_ const shared_ptr<IViewMode
|
|||
{
|
||||
m_vmCurrencyCallback = newCallback;
|
||||
|
||||
shared_ptr<ICurrencyConverterDataLoader> currencyDataLoader = GetCurrencyConverterDataLoader();
|
||||
const shared_ptr<ICurrencyConverterDataLoader> currencyDataLoader = GetCurrencyConverterDataLoader();
|
||||
if (currencyDataLoader != nullptr)
|
||||
{
|
||||
currencyDataLoader->SetViewModelCallback(newCallback);
|
||||
|
@ -582,7 +585,7 @@ future<pair<bool, wstring>> UnitConverter::RefreshCurrencyRatios()
|
|||
});
|
||||
}
|
||||
|
||||
shared_ptr<ICurrencyConverterDataLoader> UnitConverter::GetCurrencyConverterDataLoader()
|
||||
shared_ptr<ICurrencyConverterDataLoader> UnitConverter::GetCurrencyConverterDataLoader() const
|
||||
{
|
||||
return dynamic_pointer_cast<ICurrencyConverterDataLoader>(m_currencyDataLoader);
|
||||
}
|
||||
|
@ -600,7 +603,7 @@ double UnitConverter::Convert(double value, const ConversionData& conversionData
|
|||
}
|
||||
else
|
||||
{
|
||||
return (value * conversionData.ratio) + conversionData.offset;
|
||||
return value * conversionData.ratio + conversionData.offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -636,7 +639,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
|||
}
|
||||
|
||||
// Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
|
||||
sort(intermediateVector.begin(), intermediateVector.end(), [](SuggestedValueIntermediate first, SuggestedValueIntermediate second) {
|
||||
sort(intermediateVector.begin(), intermediateVector.end(), [](SuggestedValueIntermediate first, const SuggestedValueIntermediate second) {
|
||||
if (abs(first.magnitude) == abs(second.magnitude))
|
||||
{
|
||||
return first.magnitude > second.magnitude;
|
||||
|
@ -672,7 +675,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
|||
|
||||
// The Whimsicals are determined differently
|
||||
// Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
|
||||
sort(intermediateWhimsicalVector.begin(), intermediateWhimsicalVector.end(), [](SuggestedValueIntermediate first, SuggestedValueIntermediate second) {
|
||||
sort(intermediateWhimsicalVector.begin(), intermediateWhimsicalVector.end(), [](const SuggestedValueIntermediate first, const SuggestedValueIntermediate second) {
|
||||
if (abs(first.magnitude) == abs(second.magnitude))
|
||||
{
|
||||
return first.magnitude > second.magnitude;
|
||||
|
@ -797,7 +800,7 @@ void UnitConverter::InitializeSelectedUnits()
|
|||
return;
|
||||
}
|
||||
|
||||
auto itr = m_categoryToUnits.find(m_currentCategory.id);
|
||||
const auto itr = m_categoryToUnits.find(m_currentCategory.id);
|
||||
if (itr == m_categoryToUnits.end())
|
||||
{
|
||||
return;
|
||||
|
@ -856,7 +859,7 @@ void UnitConverter::ClearValues()
|
|||
/// <summary>
|
||||
/// Checks if either unit is EMPTY_UNIT.
|
||||
/// </summary>
|
||||
bool UnitConverter::AnyUnitIsEmpty()
|
||||
bool UnitConverter::AnyUnitIsEmpty() const
|
||||
{
|
||||
return m_fromType == EMPTY_UNIT || m_toType == EMPTY_UNIT;
|
||||
}
|
||||
|
@ -876,7 +879,7 @@ void UnitConverter::Calculate()
|
|||
}
|
||||
|
||||
unordered_map<Unit, ConversionData, UnitHash> conversionTable = m_ratioMap[m_fromType];
|
||||
if (AnyUnitIsEmpty() || (conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0))
|
||||
if (AnyUnitIsEmpty() || conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0)
|
||||
{
|
||||
m_returnDisplay = m_currentDisplay;
|
||||
m_returnHasDecimal = m_currentHasDecimal;
|
||||
|
@ -884,11 +887,10 @@ void UnitConverter::Calculate()
|
|||
}
|
||||
else
|
||||
{
|
||||
double currentValue = stod(m_currentDisplay);
|
||||
const double currentValue = stod(m_currentDisplay);
|
||||
const double returnValue = Convert(currentValue, conversionTable[m_toType]);
|
||||
|
||||
const auto isCurrencyConverter = m_currencyDataLoader != nullptr && m_currencyDataLoader->SupportsCategory(this->m_currentCategory);
|
||||
if (isCurrencyConverter)
|
||||
if (const auto isCurrencyConverter = m_currencyDataLoader != nullptr && m_currencyDataLoader->SupportsCategory(this->m_currentCategory))
|
||||
{
|
||||
// We don't need to trim the value when it's a currency.
|
||||
m_returnDisplay = RoundSignificantDigits(returnValue, MAXIMUMDIGITSALLOWED);
|
||||
|
@ -897,7 +899,7 @@ void UnitConverter::Calculate()
|
|||
else
|
||||
{
|
||||
const unsigned int numPreDecimal = GetNumberDigitsWholeNumberPart(returnValue);
|
||||
if (numPreDecimal > MAXIMUMDIGITSALLOWED || (returnValue != 0 && abs(returnValue) < MINIMUMDECIMALALLOWED))
|
||||
if (numPreDecimal > MAXIMUMDIGITSALLOWED || returnValue != 0 && abs(returnValue) < MINIMUMDECIMALALLOWED)
|
||||
{
|
||||
m_returnDisplay = ToScientificNumber(returnValue);
|
||||
}
|
||||
|
@ -913,30 +915,31 @@ void UnitConverter::Calculate()
|
|||
{
|
||||
// Fewer digits are needed following the decimal if the number is large,
|
||||
// we calculate the number of decimals necessary based on the number of digits in the integer part.
|
||||
auto numberDigits = max(OPTIMALDIGITSALLOWED, min(MAXIMUMDIGITSALLOWED, currentNumberSignificantDigits));
|
||||
const auto numberDigits = max(OPTIMALDIGITSALLOWED, min(MAXIMUMDIGITSALLOWED, currentNumberSignificantDigits));
|
||||
precision = numberDigits > numPreDecimal ? numberDigits - numPreDecimal : 0;
|
||||
}
|
||||
|
||||
m_returnDisplay = RoundSignificantDigits(returnValue, precision);
|
||||
TrimTrailingZeros(m_returnDisplay);
|
||||
}
|
||||
m_returnHasDecimal = (m_returnDisplay.find(L'.') != wstring::npos);
|
||||
m_returnHasDecimal = m_returnDisplay.find(L'.') != wstring::npos;
|
||||
}
|
||||
}
|
||||
UpdateViewModel();
|
||||
}
|
||||
|
||||
void UnitConverter::UpdateCurrencySymbols()
|
||||
void UnitConverter::UpdateCurrencySymbols() const
|
||||
{
|
||||
if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr)
|
||||
if (m_currencyDataLoader == nullptr || m_vmCurrencyCallback == nullptr)
|
||||
{
|
||||
shared_ptr<ICurrencyConverterDataLoader> currencyDataLoader = GetCurrencyConverterDataLoader();
|
||||
return;
|
||||
}
|
||||
const shared_ptr<ICurrencyConverterDataLoader> currencyDataLoader = GetCurrencyConverterDataLoader();
|
||||
const pair<wstring, wstring> currencySymbols = currencyDataLoader->GetCurrencySymbols(m_fromType, m_toType);
|
||||
const pair<wstring, wstring> currencyRatios = currencyDataLoader->GetCurrencyRatioEquality(m_fromType, m_toType);
|
||||
|
||||
m_vmCurrencyCallback->CurrencySymbolsCallback(currencySymbols.first, currencySymbols.second);
|
||||
m_vmCurrencyCallback->CurrencyRatiosCallback(currencyRatios.first, currencyRatios.second);
|
||||
}
|
||||
}
|
||||
|
||||
void UnitConverter::UpdateViewModel()
|
||||
|
|
|
@ -15,9 +15,8 @@ namespace UnitConversionManager
|
|||
|
||||
struct Unit
|
||||
{
|
||||
Unit()
|
||||
{
|
||||
}
|
||||
Unit() = default;
|
||||
|
||||
Unit(int id, std::wstring_view name, std::wstring abbreviation, bool isConversionSource, bool isConversionTarget, bool isWhimsical)
|
||||
: id(id)
|
||||
, name(name)
|
||||
|
@ -43,8 +42,8 @@ namespace UnitConversionManager
|
|||
, isConversionTarget(isConversionTarget)
|
||||
, isWhimsical(false)
|
||||
{
|
||||
auto nameValue1 = isRtlLanguage ? currencyName : countryName;
|
||||
auto nameValue2 = isRtlLanguage ? countryName : currencyName;
|
||||
const auto nameValue1 = isRtlLanguage ? currencyName : countryName;
|
||||
const auto nameValue2 = isRtlLanguage ? countryName : currencyName;
|
||||
|
||||
name = nameValue1;
|
||||
name.append(L" - ").append(nameValue2);
|
||||
|
@ -81,9 +80,7 @@ namespace UnitConversionManager
|
|||
|
||||
struct Category
|
||||
{
|
||||
Category()
|
||||
{
|
||||
}
|
||||
Category() = default;
|
||||
|
||||
Category(int id, std::wstring name, bool supportsNegative)
|
||||
: id(id)
|
||||
|
@ -125,9 +122,8 @@ namespace UnitConversionManager
|
|||
|
||||
struct ConversionData
|
||||
{
|
||||
ConversionData()
|
||||
{
|
||||
}
|
||||
ConversionData() = default;
|
||||
|
||||
ConversionData(double ratio, double offset, bool offsetFirst)
|
||||
: ratio(ratio)
|
||||
, offset(offset)
|
||||
|
@ -156,18 +152,17 @@ namespace UnitConversionManager
|
|||
std::wstring targetCurrencyCode;
|
||||
};
|
||||
|
||||
typedef std::tuple<std::vector<UnitConversionManager::Unit>, UnitConversionManager::Unit, UnitConversionManager::Unit> CategorySelectionInitializer;
|
||||
typedef std::unordered_map<
|
||||
using CategorySelectionInitializer = std::tuple<std::vector<UnitConversionManager::Unit>, UnitConversionManager::Unit, UnitConversionManager::Unit>;
|
||||
using UnitToUnitToConversionDataMap = std::unordered_map<
|
||||
UnitConversionManager::Unit,
|
||||
std::unordered_map<UnitConversionManager::Unit, UnitConversionManager::ConversionData, UnitConversionManager::UnitHash>,
|
||||
UnitConversionManager::UnitHash>
|
||||
UnitToUnitToConversionDataMap;
|
||||
typedef std::unordered_map<int, std::vector<UnitConversionManager::Unit>> CategoryToUnitVectorMap;
|
||||
UnitConversionManager::UnitHash>;
|
||||
using CategoryToUnitVectorMap = std::unordered_map<int, std::vector<UnitConversionManager::Unit>>;
|
||||
|
||||
class IViewModelCurrencyCallback
|
||||
{
|
||||
public:
|
||||
virtual ~IViewModelCurrencyCallback(){};
|
||||
virtual ~IViewModelCurrencyCallback() = default;
|
||||
virtual void CurrencyDataLoadFinished(bool didLoad) = 0;
|
||||
virtual void CurrencySymbolsCallback(_In_ const std::wstring& fromSymbol, _In_ const std::wstring& toSymbol) = 0;
|
||||
virtual void CurrencyRatiosCallback(_In_ const std::wstring& ratioEquality, _In_ const std::wstring& accRatioEquality) = 0;
|
||||
|
@ -178,7 +173,7 @@ namespace UnitConversionManager
|
|||
class IConverterDataLoader
|
||||
{
|
||||
public:
|
||||
virtual ~IConverterDataLoader(){};
|
||||
virtual ~IConverterDataLoader() = default;
|
||||
virtual void LoadData() = 0; // prepare data if necessary before calling other functions
|
||||
virtual std::vector<Category> GetOrderedCategories() = 0;
|
||||
virtual std::vector<Unit> GetOrderedUnits(const Category& c) = 0;
|
||||
|
@ -204,7 +199,7 @@ namespace UnitConversionManager
|
|||
class IUnitConverterVMCallback
|
||||
{
|
||||
public:
|
||||
virtual ~IUnitConverterVMCallback(){};
|
||||
virtual ~IUnitConverterVMCallback() = default;
|
||||
virtual void DisplayCallback(const std::wstring& from, const std::wstring& to) = 0;
|
||||
virtual void SuggestedValueCallback(const std::vector<std::tuple<std::wstring, Unit>>& suggestedValues) = 0;
|
||||
virtual void MaxDigitsReached() = 0;
|
||||
|
@ -213,9 +208,7 @@ namespace UnitConversionManager
|
|||
class IUnitConverter
|
||||
{
|
||||
public:
|
||||
virtual ~IUnitConverter()
|
||||
{
|
||||
}
|
||||
virtual ~IUnitConverter() = default;
|
||||
virtual void Initialize() = 0; // Use to initialize first time, use deserialize instead to rehydrate
|
||||
virtual std::vector<Category> GetCategories() = 0;
|
||||
virtual CategorySelectionInitializer SetCurrentCategory(const Category& input) = 0;
|
||||
|
@ -263,21 +256,20 @@ namespace UnitConversionManager
|
|||
|
||||
private:
|
||||
bool CheckLoad();
|
||||
double Convert(double value, const ConversionData& conversionData);
|
||||
static double Convert(double value, const ConversionData& conversionData);
|
||||
std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested();
|
||||
void ClearValues();
|
||||
void InitializeSelectedUnits();
|
||||
Category StringToCategory(std::wstring_view w);
|
||||
std::wstring CategoryToString(const Category& c, std::wstring_view delimiter);
|
||||
std::wstring UnitToString(const Unit& u, std::wstring_view delimiter);
|
||||
Unit StringToUnit(std::wstring_view w);
|
||||
void UpdateCurrencySymbols();
|
||||
static Category StringToCategory(std::wstring_view w);
|
||||
std::wstring CategoryToString(const Category& c, std::wstring_view delimiter) const;
|
||||
std::wstring UnitToString(const Unit& u, std::wstring_view delimiter) const;
|
||||
static Unit StringToUnit(std::wstring_view w);
|
||||
void UpdateCurrencySymbols() const;
|
||||
void UpdateViewModel();
|
||||
bool AnyUnitIsEmpty();
|
||||
bool AnyUnitIsEmpty() const;
|
||||
std::shared_ptr<IConverterDataLoader> GetDataLoaderForCategory(const Category& category);
|
||||
std::shared_ptr<ICurrencyConverterDataLoader> GetCurrencyConverterDataLoader();
|
||||
std::shared_ptr<ICurrencyConverterDataLoader> GetCurrencyConverterDataLoader() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<IConverterDataLoader> m_dataLoader;
|
||||
std::shared_ptr<IConverterDataLoader> m_currencyDataLoader;
|
||||
std::shared_ptr<IUnitConverterVMCallback> m_vmCallback;
|
||||
|
|
|
@ -288,9 +288,8 @@ bool CopyPasteManager::ExpressionRegExMatch(
|
|||
}
|
||||
else if (mode == ViewMode::Programmer)
|
||||
{
|
||||
patterns.assign(
|
||||
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].begin(),
|
||||
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].end());
|
||||
auto pattern = &programmerModePatterns[static_cast<int>(programmerNumberBase) - static_cast<int>(NumberBase::HexBase)];
|
||||
patterns.assign(pattern->begin(), pattern->end());
|
||||
}
|
||||
else if (modeType == CategoryGroupType::Converter)
|
||||
{
|
||||
|
@ -505,9 +504,7 @@ ULONG32 CopyPasteManager::StandardScientificOperandLength(Platform::String ^ ope
|
|||
const bool hasDecimal = operandWstring.find('.') != wstring::npos;
|
||||
auto length = operandWstring.length();
|
||||
|
||||
if (hasDecimal)
|
||||
{
|
||||
if (length >= 2)
|
||||
if (hasDecimal && length >= 2)
|
||||
{
|
||||
if ((operandWstring[0] == L'0') && (operandWstring[1] == L'.'))
|
||||
{
|
||||
|
@ -518,7 +515,6 @@ ULONG32 CopyPasteManager::StandardScientificOperandLength(Platform::String ^ ope
|
|||
length -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto exponentPos = operandWstring.find('e');
|
||||
const bool hasExponent = exponentPos != wstring::npos;
|
||||
|
|
|
@ -171,7 +171,6 @@ IBox<DateDifference> ^ DateCalculationEngine::TryGetDateDifference(_In_ DateTime
|
|||
|
||||
if (static_cast<int>(outputFormat & dateUnit))
|
||||
{
|
||||
bool isEndDateHit = false;
|
||||
differenceInDates[unitIndex] = (daysDiff / daysIn[unitIndex]);
|
||||
|
||||
if (differenceInDates[unitIndex] != 0)
|
||||
|
@ -188,11 +187,12 @@ IBox<DateDifference> ^ DateCalculationEngine::TryGetDateDifference(_In_ DateTime
|
|||
}
|
||||
}
|
||||
|
||||
int tempDaysDiff;
|
||||
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
tempDaysDiff = GetDifferenceInDays(pivotDate, endDate);
|
||||
int tempDaysDiff = GetDifferenceInDays(pivotDate, endDate);
|
||||
|
||||
if (tempDaysDiff == 0)
|
||||
break;
|
||||
|
||||
if (tempDaysDiff < 0)
|
||||
{
|
||||
|
@ -205,12 +205,6 @@ IBox<DateDifference> ^ DateCalculationEngine::TryGetDateDifference(_In_ DateTime
|
|||
differenceInDates[unitIndex] -= 1;
|
||||
pivotDate = tempPivotDate;
|
||||
pivotDate = AdjustCalendarDate(pivotDate, dateUnit, static_cast<int>(differenceInDates[unitIndex]));
|
||||
isEndDateHit = true;
|
||||
}
|
||||
else if (tempDaysDiff > 0)
|
||||
{
|
||||
if (isEndDateHit)
|
||||
{
|
||||
// This is the closest the pivot can get to the end date for this unit
|
||||
break;
|
||||
}
|
||||
|
@ -228,7 +222,6 @@ IBox<DateDifference> ^ DateCalculationEngine::TryGetDateDifference(_In_ DateTime
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
} while (tempDaysDiff != 0); // dates are the same - exit the loop
|
||||
|
||||
tempPivotDate = AdjustCalendarDate(tempPivotDate, dateUnit, static_cast<int>(differenceInDates[unitIndex]));
|
||||
pivotDate = tempPivotDate;
|
||||
|
@ -269,34 +262,33 @@ int DateCalculationEngine::GetDifferenceInDays(DateTime date1, DateTime date2)
|
|||
// Returns true if successful, false otherwise.
|
||||
bool DateCalculationEngine::TryGetCalendarDaysInMonth(_In_ DateTime date, _Out_ UINT& daysInMonth)
|
||||
{
|
||||
bool result = false;
|
||||
m_calendar->SetDateTime(date);
|
||||
|
||||
// NumberOfDaysInThisMonth returns -1 if unknown.
|
||||
int daysInThisMonth = m_calendar->NumberOfDaysInThisMonth;
|
||||
if (daysInThisMonth != -1)
|
||||
if (daysInThisMonth == -1)
|
||||
{
|
||||
daysInMonth = static_cast<UINT>(daysInThisMonth);
|
||||
result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
daysInMonth = static_cast<UINT>(daysInThisMonth);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gets number of Calendar days in the year in which this date falls.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool DateCalculationEngine::TryGetCalendarDaysInYear(_In_ DateTime date, _Out_ UINT& daysInYear)
|
||||
{
|
||||
bool result = false;
|
||||
UINT days = 0;
|
||||
|
||||
m_calendar->SetDateTime(date);
|
||||
|
||||
// NumberOfMonthsInThisYear returns -1 if unknown.
|
||||
int monthsInYear = m_calendar->NumberOfMonthsInThisYear;
|
||||
if (monthsInYear != -1)
|
||||
if (monthsInYear == -1)
|
||||
{
|
||||
bool monthResult = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not all years begin with Month 1.
|
||||
int firstMonthThisYear = m_calendar->FirstMonthInThisYear;
|
||||
|
@ -308,21 +300,14 @@ bool DateCalculationEngine::TryGetCalendarDaysInYear(_In_ DateTime date, _Out_ U
|
|||
int daysInMonth = m_calendar->NumberOfDaysInThisMonth;
|
||||
if (daysInMonth == -1)
|
||||
{
|
||||
monthResult = false;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
days += daysInMonth;
|
||||
}
|
||||
|
||||
if (monthResult)
|
||||
{
|
||||
daysInYear = days;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds/Subtracts certain value for a particular date unit
|
||||
|
@ -342,17 +327,17 @@ DateTime DateCalculationEngine::AdjustCalendarDate(Windows::Foundation::DateTime
|
|||
m_calendar->ChangeCalendarSystem(CalendarIdentifiers::Gregorian);
|
||||
}
|
||||
|
||||
switch (dateUnit)
|
||||
if (dateUnit == DateUnit::Year)
|
||||
{
|
||||
case DateUnit::Year:
|
||||
m_calendar->AddYears(difference);
|
||||
break;
|
||||
case DateUnit::Month:
|
||||
}
|
||||
else if (dateUnit == DateUnit::Month)
|
||||
{
|
||||
m_calendar->AddMonths(difference);
|
||||
break;
|
||||
case DateUnit::Week:
|
||||
}
|
||||
else if (dateUnit == DateUnit::Week)
|
||||
{
|
||||
m_calendar->AddWeeks(difference);
|
||||
break;
|
||||
}
|
||||
|
||||
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
|
||||
|
|
|
@ -39,8 +39,7 @@ namespace CalculatorApp
|
|||
// 3;2;0 0x023 - group 1st 3 and then every 2 digits
|
||||
// 4;0 0x004 - group every 4 digits
|
||||
// 5;3;2;0 0x235 - group 5, then 3, then every 2
|
||||
wstring numberGroupingString = localizationSettings->GetNumberGroupingStr();
|
||||
return numberGroupingString;
|
||||
return localizationSettings->GetNumberGroupingStr();
|
||||
}
|
||||
|
||||
StringReference idRef(id.data(), id.length());
|
||||
|
|
|
@ -17,24 +17,16 @@ std::shared_ptr<IExpressionCommand> CommandDeserializer::Deserialize(_In_ Calcul
|
|||
switch (cmdType)
|
||||
{
|
||||
case CalculationManager::CommandType::OperandCommand:
|
||||
|
||||
return std::make_shared<COpndCommand>(DeserializeOperand());
|
||||
break;
|
||||
|
||||
case CalculationManager::CommandType::Parentheses:
|
||||
|
||||
return std::make_shared<CParentheses>(DeserializeParentheses());
|
||||
break;
|
||||
|
||||
case CalculationManager::CommandType::UnaryCommand:
|
||||
|
||||
return std::make_shared<CUnaryCommand>(DeserializeUnary());
|
||||
break;
|
||||
|
||||
case CalculationManager::CommandType::BinaryCommand:
|
||||
|
||||
return std::make_shared<CBinaryCommand>(DeserializeBinary());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ref new Platform::Exception(E_INVALIDARG, ref new Platform::String(L"Unknown command type"));
|
||||
|
@ -50,7 +42,7 @@ COpndCommand CommandDeserializer::DeserializeOperand()
|
|||
std::shared_ptr<std::vector<int>> cmdVector = std::make_shared<std::vector<int>>();
|
||||
auto cmdVectorSize = m_dataReader->ReadUInt32();
|
||||
|
||||
for (unsigned int j = 0; j < cmdVectorSize; ++j)
|
||||
for (auto j = cmdVectorSize; j > 0; --j)
|
||||
{
|
||||
int eachOpndcmd = m_dataReader->ReadInt32();
|
||||
cmdVector->push_back(eachOpndcmd);
|
||||
|
|
|
@ -84,9 +84,9 @@ LocalizationService::LocalizationService(_In_ const wchar_t * const overridedLan
|
|||
try
|
||||
{
|
||||
// Convert wstring to string for locale
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &localeName[0], (int)localeName.size(), NULL, 0, NULL, NULL);
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &localeName[0], static_cast<int>(localeName.size()), NULL, 0, NULL, NULL);
|
||||
string localeNameStr(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, &localeName[0], (int)localeName.size(), &localeNameStr[0], size_needed, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, &localeName[0], static_cast<int>(localeName.size()), &localeNameStr[0], size_needed, NULL, NULL);
|
||||
|
||||
m_locale = locale(localeNameStr.data());
|
||||
}
|
||||
|
|
|
@ -188,7 +188,6 @@ namespace CalculatorApp::ViewModel
|
|||
return m_listSeparator;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void Initialize(Windows::Globalization::NumberFormatting::DecimalFormatter ^ formatter)
|
||||
{
|
||||
|
@ -346,7 +345,7 @@ namespace CalculatorApp::ViewModel
|
|||
int m_currencySymbolPrecedence;
|
||||
Platform::String ^ m_resolvedName;
|
||||
int m_currencyTrailingDigits;
|
||||
static const unsigned int LocaleSettingBufferSize = 16;
|
||||
static constexpr unsigned int LocaleSettingBufferSize = 16;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace CalculatorApp::ViewModel
|
|||
{
|
||||
std::wstring returnString = L"";
|
||||
const UINT32 length = 1024;
|
||||
std::unique_ptr<wchar_t[]> spBuffer = std::unique_ptr<wchar_t[]>(new wchar_t[length]);
|
||||
std::unique_ptr<wchar_t[]> spBuffer = std::make_unique<wchar_t[]>(length);
|
||||
va_list args = NULL;
|
||||
va_start(args, pMessage);
|
||||
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pMessage->Data(), 0, 0, spBuffer.get(), length, &args);
|
||||
|
|
|
@ -104,7 +104,6 @@ namespace CalculatorApp
|
|||
if (NavCategoryStates::IsValidViewMode(mode))
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
;
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_MODE_CHANGED), fields);
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ namespace Utils
|
|||
template <typename T>
|
||||
struct IsRefClass
|
||||
{
|
||||
static const bool value = __is_ref_class(T);
|
||||
static constexpr bool value = __is_ref_class(T);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -277,7 +277,7 @@ double CurrencyDataLoader::RoundCurrencyRatio(double ratio)
|
|||
{
|
||||
numberDecimals = max(
|
||||
FORMATTER_RATE_MIN_DECIMALS,
|
||||
(int)(-log10(ratio)) + FORMATTER_RATE_MIN_SIGNIFICANT_DECIMALS);
|
||||
static_cast<int>(-log10(ratio)) + FORMATTER_RATE_MIN_SIGNIFICANT_DECIMALS);
|
||||
}
|
||||
|
||||
unsigned long long scale = (unsigned long long)powl(10l, numberDecimals);
|
||||
|
|
|
@ -45,7 +45,7 @@ DateCalculatorViewModel::DateCalculatorViewModel()
|
|||
, m_StrDateResult(L"")
|
||||
, m_StrDateResultAutomationName(L"")
|
||||
{
|
||||
LocalizationSettings^ localizationSettings = LocalizationSettings::GetInstance();
|
||||
LocalizationSettings ^ localizationSettings = LocalizationSettings::GetInstance();
|
||||
|
||||
// Initialize Date Output format instances
|
||||
InitializeDateOutputFormats(localizationSettings->GetCalendarIdentifier());
|
||||
|
@ -74,7 +74,7 @@ DateCalculatorViewModel::DateCalculatorViewModel()
|
|||
UpdateDisplayResult();
|
||||
|
||||
m_offsetValues = ref new Vector<String ^>();
|
||||
for (int i = 0; i <= c_maxOffsetValue; i++)
|
||||
for (unsigned int i = 0; i <= c_maxOffsetValue; i++)
|
||||
{
|
||||
wstring numberStr(to_wstring(i));
|
||||
localizationSettings->LocalizeDisplayValue(&numberStr);
|
||||
|
@ -157,10 +157,14 @@ void DateCalculatorViewModel::OnInputsChanged()
|
|||
// Subtract number of Days, Months and Years from a Date
|
||||
dateTimeResult = m_dateCalcEngine->SubtractDuration(StartDate, dateDiff);
|
||||
}
|
||||
IsOutOfBound = dateTimeResult == nullptr;
|
||||
|
||||
if (!m_isOutOfBound)
|
||||
if (dateTimeResult == nullptr)
|
||||
{
|
||||
IsOutOfBound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsOutOfBound = false;
|
||||
DateResult = dateTimeResult->Value;
|
||||
}
|
||||
}
|
||||
|
@ -254,13 +258,13 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
|||
result += GetLocalizedNumberString(yearCount)->Data();
|
||||
result += L' ';
|
||||
|
||||
if (yearCount > 1)
|
||||
if (yearCount == 1)
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Years")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Year")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Year")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Years")->Data();
|
||||
}
|
||||
|
||||
// set the flags to add a delimiter whenever the next unit is added
|
||||
|
@ -282,13 +286,13 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
|||
result += GetLocalizedNumberString(monthCount)->Data();
|
||||
result += L' ';
|
||||
|
||||
if (monthCount > 1)
|
||||
if (monthCount == 1)
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Months")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Month")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Month")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Months")->Data();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,13 +311,13 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
|||
result += GetLocalizedNumberString(weekCount)->Data();
|
||||
result += L' ';
|
||||
|
||||
if (weekCount > 1)
|
||||
if (weekCount == 1)
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Weeks")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Week")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Week")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Weeks")->Data();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,13 +336,13 @@ String ^ DateCalculatorViewModel::GetDateDiffString() const
|
|||
result += GetLocalizedNumberString(dayCount)->Data();
|
||||
result += L' ';
|
||||
|
||||
if (dayCount > 1)
|
||||
if (dayCount == 1)
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Days")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Day")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += resourceLoader->GetResourceString(L"Date_Day")->Data();
|
||||
result += resourceLoader->GetResourceString(L"Date_Days")->Data();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,13 +355,13 @@ String ^ DateCalculatorViewModel::GetDateDiffStringInDays() const
|
|||
result += L' ';
|
||||
|
||||
// Display the result as '1 day' or 'N days'
|
||||
if (m_dateDiffResultInDays.day > 1)
|
||||
if (m_dateDiffResultInDays.day == 1)
|
||||
{
|
||||
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Days")->Data();
|
||||
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Day")->Data();
|
||||
}
|
||||
else
|
||||
{
|
||||
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Day")->Data();
|
||||
result += AppResourceProvider::GetInstance()->GetResourceString(L"Date_Days")->Data();
|
||||
}
|
||||
|
||||
return ref new String(result.data());
|
||||
|
@ -365,14 +369,7 @@ String ^ DateCalculatorViewModel::GetDateDiffStringInDays() const
|
|||
|
||||
void DateCalculatorViewModel::OnCopyCommand(Platform::Object ^ parameter)
|
||||
{
|
||||
if (m_IsDateDiffMode)
|
||||
{
|
||||
CopyPasteManager::CopyToClipboard(m_StrDateDiffResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyPasteManager::CopyToClipboard(m_StrDateResult);
|
||||
}
|
||||
CopyPasteManager::CopyToClipboard(m_IsDateDiffMode ? m_StrDateDiffResult : m_StrDateResult);
|
||||
}
|
||||
|
||||
String ^ DateCalculatorViewModel::GetLocalizedNumberString(int value) const
|
||||
|
@ -393,15 +390,13 @@ DateTime DateCalculatorViewModel::ClipTime(DateTime dateTime, bool adjustUsingLo
|
|||
if (adjustUsingLocalTime)
|
||||
{
|
||||
FILETIME fileTime;
|
||||
fileTime.dwLowDateTime = (DWORD)(dateTime.UniversalTime & 0xffffffff);
|
||||
fileTime.dwHighDateTime = (DWORD)(dateTime.UniversalTime >> 32);
|
||||
fileTime.dwLowDateTime = static_cast<DWORD>(dateTime.UniversalTime & 0xffffffff);
|
||||
fileTime.dwHighDateTime = static_cast<DWORD>(dateTime.UniversalTime >> 32);
|
||||
|
||||
FILETIME localFileTime;
|
||||
FileTimeToLocalFileTime(&fileTime, &localFileTime);
|
||||
|
||||
referenceDateTime.UniversalTime = (DWORD)localFileTime.dwHighDateTime;
|
||||
referenceDateTime.UniversalTime <<= 32;
|
||||
referenceDateTime.UniversalTime |= (DWORD)localFileTime.dwLowDateTime;
|
||||
referenceDateTime.UniversalTime = (static_cast<INT64>(localFileTime.dwHighDateTime) << 32) | localFileTime.dwLowDateTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "Common/Utils.h"
|
||||
#include "Common/DateCalculator.h"
|
||||
|
||||
const int c_maxOffsetValue = 999;
|
||||
constexpr unsigned int c_maxOffsetValue = 999;
|
||||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
|
|
|
@ -30,9 +30,9 @@ void GraphingSettingsViewModel::SetGrapher(Grapher ^ grapher)
|
|||
{
|
||||
if (grapher != nullptr)
|
||||
{
|
||||
if (grapher->TrigUnitMode == (int)Graphing::EvalTrigUnitMode::Invalid)
|
||||
if (grapher->TrigUnitMode == static_cast<int>(Graphing::EvalTrigUnitMode::Invalid))
|
||||
{
|
||||
grapher->TrigUnitMode = (int)Graphing::EvalTrigUnitMode::Radians;
|
||||
grapher->TrigUnitMode = static_cast<int>(Graphing::EvalTrigUnitMode::Radians);
|
||||
}
|
||||
}
|
||||
Graph = grapher;
|
||||
|
|
|
@ -116,13 +116,13 @@ void HistoryViewModel::ShowItem(_In_ HistoryItemViewModel ^ e)
|
|||
{
|
||||
unsigned int index;
|
||||
Items->IndexOf(e, &index);
|
||||
TraceLogger::GetInstance()->LogHistoryItemLoad((ViewMode)m_currentMode, Items->Size, (int)(index));
|
||||
TraceLogger::GetInstance()->LogHistoryItemLoad((ViewMode)m_currentMode, Items->Size, static_cast<int>(index));
|
||||
HistoryItemClicked(e);
|
||||
}
|
||||
|
||||
void HistoryViewModel::DeleteItem(_In_ HistoryItemViewModel ^ e)
|
||||
{
|
||||
uint32_t itemIndex;
|
||||
unsigned int itemIndex;
|
||||
if (Items->IndexOf(e, &itemIndex))
|
||||
{
|
||||
if (m_calculatorManager->RemoveHistoryItem(itemIndex))
|
||||
|
|
|
@ -1552,7 +1552,7 @@ wstring StandardCalculatorViewModel::AddPadding(wstring binaryString)
|
|||
{
|
||||
return binaryString;
|
||||
}
|
||||
size_t pad = 4 - LengthWithoutPadding(binaryString) % 4;
|
||||
size_t pad = 4 - (LengthWithoutPadding(binaryString) & 3);
|
||||
if (pad == 4)
|
||||
{
|
||||
pad = 0;
|
||||
|
|
|
@ -277,7 +277,7 @@ void UnitConverterViewModel::OnSwitchActive(Platform::Object ^ unused)
|
|||
|
||||
String ^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings, CurrencyFormatterParameter cfp)
|
||||
{
|
||||
Platform::String ^ result;
|
||||
Platform::String ^ result = nullptr;
|
||||
|
||||
if (stringToLocalize.empty())
|
||||
{
|
||||
|
@ -693,7 +693,8 @@ void UnitConverterViewModel::RefreshCurrencyRatios()
|
|||
auto that(this);
|
||||
auto refreshTask = create_task([that] { return that->m_model->RefreshCurrencyRatios().get(); });
|
||||
refreshTask.then(
|
||||
[that](const pair<bool, wstring>& refreshResult) {
|
||||
[that](const pair<bool, wstring>& refreshResult)
|
||||
{
|
||||
bool didLoad = refreshResult.first;
|
||||
wstring timestamp = refreshResult.second;
|
||||
|
||||
|
|
|
@ -42,14 +42,3 @@
|
|||
#include "winrt/Windows.UI.Xaml.h"
|
||||
#include "winrt/Windows.Foundation.Metadata.h"
|
||||
#include "winrt/Windows.Management.Policies.h"
|
||||
|
||||
// The following namespaces exist as a convenience to resolve
|
||||
// ambiguity for Windows types in the Windows::UI::Xaml::Automation::Peers
|
||||
// namespace that only exist on RS3.
|
||||
// Once the app switches to min version RS3, the namespaces can be removed.
|
||||
// TODO - MSFT 12735088
|
||||
namespace StandardPeers = Windows::UI::Xaml::Automation::Peers;
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
}
|
||||
namespace CustomPeers = CalculatorApp::ViewModel::Common::Automation;
|
||||
|
|
|
@ -16,9 +16,7 @@ namespace DateCalculationUnitTests
|
|||
SystemTimeToFileTime(&systemTime, lpFileTime);
|
||||
|
||||
Windows::Foundation::DateTime dateTime;
|
||||
dateTime.UniversalTime = (DWORD)lpFileTime->dwHighDateTime;
|
||||
dateTime.UniversalTime <<= 32;
|
||||
dateTime.UniversalTime |= (DWORD)lpFileTime->dwLowDateTime;
|
||||
dateTime.UniversalTime = (static_cast<INT64>(lpFileTime->dwHighDateTime) << 32) | (lpFileTime->dwLowDateTime);
|
||||
|
||||
return dateTime;
|
||||
}
|
||||
|
@ -28,8 +26,8 @@ namespace DateCalculationUnitTests
|
|||
static SYSTEMTIME DateTimeToSystemTime(Windows::Foundation::DateTime dateTime)
|
||||
{
|
||||
FILETIME fileTime;
|
||||
fileTime.dwLowDateTime = (DWORD)(dateTime.UniversalTime & 0xffffffff);
|
||||
fileTime.dwHighDateTime = (DWORD)(dateTime.UniversalTime >> 32);
|
||||
fileTime.dwLowDateTime = static_cast<DWORD>(dateTime.UniversalTime & 0xffffffff);
|
||||
fileTime.dwHighDateTime = static_cast<DWORD>(dateTime.UniversalTime >> 32);
|
||||
|
||||
SYSTEMTIME systemTime;
|
||||
FileTimeToSystemTime(&fileTime, &systemTime);
|
||||
|
|
|
@ -83,12 +83,12 @@ namespace CalculatorFunctionalTests
|
|||
void AddSingleHistoryItem()
|
||||
{
|
||||
Initialize();
|
||||
int initialSize = m_historyViewModel->ItemsCount;
|
||||
auto initialSize = m_historyViewModel->ItemsCount;
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::Command1));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::CommandADD));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::Command8));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::CommandEQU));
|
||||
int sizeAfterItemAdd = m_historyViewModel->ItemsCount;
|
||||
auto sizeAfterItemAdd = m_historyViewModel->ItemsCount;
|
||||
auto historyItem = static_cast<HistoryItemViewModel ^>(m_historyViewModel->Items->GetAt(0));
|
||||
String ^ expression = L"1 + 8 =";
|
||||
VERIFY_ARE_EQUAL(initialSize + 1, sizeAfterItemAdd);
|
||||
|
@ -143,7 +143,7 @@ namespace CalculatorFunctionalTests
|
|||
Command nextCommand = Command(130 + i);
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::Command1));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::CommandADD));
|
||||
m_standardViewModel->SendCommandToCalcManager((int)nextCommand);
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(nextCommand));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::CommandEQU));
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ namespace CalculatorFunctionalTests
|
|||
Command nextCommand = Command(130 + i);
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::Command1));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::CommandADD));
|
||||
m_standardViewModel->SendCommandToCalcManager((int)nextCommand);
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(nextCommand));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::CommandEQU));
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ namespace CalculatorFunctionalTests
|
|||
for (int i = 0; i < scientificItems; i++)
|
||||
{
|
||||
wstring expr = L"1 + " + wstring(i.ToString()->Data()) + L" =";
|
||||
int output = 1 + i;
|
||||
auto output = 1 + i;
|
||||
String ^ result = output.ToString();
|
||||
auto historyItem = static_cast<HistoryItemViewModel ^>(m_historyViewModel->Items->GetAt(m_historyViewModel->ItemsCount - 1 - i));
|
||||
VERIFY_ARE_EQUAL(historyItem->Expression, StringReference(expr.c_str()));
|
||||
|
@ -177,7 +177,7 @@ namespace CalculatorFunctionalTests
|
|||
for (int i = 0; i < standardItems; i++)
|
||||
{
|
||||
wstring expr = L"1 + " + wstring(i.ToString()->Data()) + L" =";
|
||||
int output = 1 + i;
|
||||
auto output = 1 + i;
|
||||
String ^ result = output.ToString();
|
||||
auto historyItem = static_cast<HistoryItemViewModel ^>(m_historyViewModel->Items->GetAt(m_historyViewModel->ItemsCount - 1 - i));
|
||||
VERIFY_ARE_EQUAL(historyItem->Expression, StringReference(expr.c_str()));
|
||||
|
@ -210,16 +210,16 @@ namespace CalculatorFunctionalTests
|
|||
Command commands[] = { Command::CommandSIN, Command::CommandCOS, Command::CommandTAN,
|
||||
Command::CommandASIN, Command::CommandACOS, Command::CommandATAN };
|
||||
Command mode[] = { Command::CommandDEG, Command::CommandRAD, Command::CommandGRAD };
|
||||
int modes = sizeof(mode) / sizeof(Command);
|
||||
int commandsSize = sizeof(commands) / sizeof(Command);
|
||||
size_t modes = sizeof(mode) / sizeof(Command);
|
||||
size_t commandsSize = sizeof(commands) / sizeof(Command);
|
||||
ResourceLoader ^ m_uiResourceLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
|
||||
int itemIndex = 0;
|
||||
int commandResource = 67;
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::ModeScientific));
|
||||
for (int index = 0; index < modes; index++)
|
||||
for (size_t index = 0; index < modes; index++)
|
||||
{
|
||||
m_standardViewModel->SendCommandToCalcManager((int)mode[index]);
|
||||
for (int command = 0; command < commandsSize; command++)
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(mode[index]));
|
||||
for (size_t command = 0; command < commandsSize; command++)
|
||||
{
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(Command::Command1));
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(commands[command]));
|
||||
|
@ -390,13 +390,13 @@ namespace CalculatorFunctionalTests
|
|||
void HistoryStandardOrderOfOperationsHelper(String ^ expectedResult, String ^ expectedExpression, Command testCommands[])
|
||||
{
|
||||
Initialize();
|
||||
int initialSize = m_historyViewModel->ItemsCount;
|
||||
auto initialSize = m_historyViewModel->ItemsCount;
|
||||
Command* currentCommand = testCommands;
|
||||
while (*currentCommand != Command::CommandNULL)
|
||||
{
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(*currentCommand++));
|
||||
}
|
||||
int sizeAfterCommandsAdd = m_historyViewModel->ItemsCount;
|
||||
auto sizeAfterCommandsAdd = m_historyViewModel->ItemsCount;
|
||||
if (expectedResult->IsEmpty())
|
||||
{
|
||||
VERIFY_ARE_EQUAL(initialSize, sizeAfterCommandsAdd);
|
||||
|
@ -554,13 +554,13 @@ namespace CalculatorFunctionalTests
|
|||
Initialize();
|
||||
Command commands[] = { Command::Command1, Command::CommandMUL, Command::Command2, Command::CommandMUL, Command::Command3,
|
||||
Command::CommandMUL, Command::Command4, Command::CommandMUL, Command::Command5, Command::CommandMUL, Command::CommandNULL };
|
||||
int initialSize = m_historyViewModel->ItemsCount;
|
||||
auto initialSize = m_historyViewModel->ItemsCount;
|
||||
Command* currentCommand = commands;
|
||||
while (*currentCommand != Command::CommandNULL)
|
||||
{
|
||||
m_standardViewModel->SendCommandToCalcManager(static_cast<int>(*currentCommand++));
|
||||
}
|
||||
int sizeAfterCommandsAdd = m_historyViewModel->ItemsCount;
|
||||
auto sizeAfterCommandsAdd = m_historyViewModel->ItemsCount;
|
||||
VERIFY_ARE_EQUAL(initialSize + 4, sizeAfterCommandsAdd);
|
||||
auto historyItem = static_cast<HistoryItemViewModel ^>(m_historyViewModel->Items->GetAt(0));
|
||||
VERIFY_ARE_EQUAL(historyItem->Expression, L"24 \x00D7 5 =");
|
||||
|
|
|
@ -728,7 +728,7 @@ namespace CalculatorUnitTests
|
|||
viewModel->DisplayValue = L"1001";
|
||||
viewModel->OnMemoryButtonPressed();
|
||||
viewModel->OnMemoryButtonPressed();
|
||||
VERIFY_ARE_EQUAL((int)viewModel->MemorizedNumbers->Size, 2);
|
||||
VERIFY_ARE_EQUAL(viewModel->MemorizedNumbers->Size, 2);
|
||||
}
|
||||
|
||||
// When memory list is empty and M+ is pressed
|
||||
|
@ -900,7 +900,7 @@ namespace CalculatorUnitTests
|
|||
{
|
||||
viewModel->OnMemoryButtonPressed();
|
||||
}
|
||||
VERIFY_ARE_EQUAL((int)viewModel->MemorizedNumbers->Size, 100);
|
||||
VERIFY_ARE_EQUAL(viewModel->MemorizedNumbers->Size, 100);
|
||||
}
|
||||
|
||||
// When memory slot is pressed verify if the display value is updated correctly
|
||||
|
|
|
@ -33,7 +33,7 @@ TEST_METHOD(IsLastCharacterFailureEmptyInput)
|
|||
|
||||
TEST_METHOD(IsLastCharacterFailureNullTarget)
|
||||
{
|
||||
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget({}, NULL));
|
||||
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget({}, L'\0'));
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
|
@ -231,14 +231,10 @@ namespace GraphControl
|
|||
{
|
||||
return;
|
||||
}
|
||||
bool keepCurrentView = true;
|
||||
|
||||
// If the equation has changed, the IsLineEnabled state is reset.
|
||||
// This checks if the equation has been reset and sets keepCurrentView to false in this case.
|
||||
if (!equation->HasGraphError && !equation->IsValidated && equation->IsLineEnabled)
|
||||
{
|
||||
keepCurrentView = false;
|
||||
}
|
||||
const bool keepCurrentView = equation->HasGraphError || equation->IsValidated || !equation->IsLineEnabled;
|
||||
|
||||
PlotGraph(keepCurrentView);
|
||||
}
|
||||
|
@ -301,8 +297,8 @@ namespace GraphControl
|
|||
}
|
||||
}
|
||||
|
||||
int valid = 0;
|
||||
int invalid = 0;
|
||||
unsigned int valid = 0;
|
||||
unsigned int invalid = 0;
|
||||
for (Equation ^ eq : Equations)
|
||||
{
|
||||
if (eq->HasGraphError)
|
||||
|
@ -396,7 +392,7 @@ namespace GraphControl
|
|||
{
|
||||
auto graphedEquations = initResult.value();
|
||||
|
||||
for (int i = 0; i < validEqs.size(); i++)
|
||||
for (size_t i = 0; i < validEqs.size(); i++)
|
||||
{
|
||||
validEqs[i]->GraphedEquation = graphedEquations[i];
|
||||
}
|
||||
|
@ -557,7 +553,9 @@ namespace GraphControl
|
|||
|
||||
if (m_graph != nullptr && m_renderMain != nullptr)
|
||||
{
|
||||
auto workItemHandler = ref new WorkItemHandler([this, variableName, newValue](IAsyncAction ^ action) {
|
||||
auto workItemHandler = ref new WorkItemHandler(
|
||||
[this, variableName, newValue](IAsyncAction ^ action)
|
||||
{
|
||||
m_renderMain->GetCriticalSection().lock();
|
||||
m_graph->SetArgValue(variableName->Data(), newValue);
|
||||
m_renderMain->GetCriticalSection().unlock();
|
||||
|
@ -618,7 +616,7 @@ namespace GraphControl
|
|||
return validEqs;
|
||||
}
|
||||
|
||||
void Grapher::OnForceProportionalAxesPropertyChanged(bool /*oldValue*/, bool newValue)
|
||||
void Grapher::OnForceProportionalAxesPropertyChanged(bool oldValue [[maybe_unused]], bool newValue)
|
||||
{
|
||||
m_calculatedForceProportional = newValue;
|
||||
TryUpdateGraph(false);
|
||||
|
@ -842,7 +840,7 @@ namespace GraphControl
|
|||
{
|
||||
// Get the raw data
|
||||
vector<BYTE> byteVector = BitmapOut->GetData();
|
||||
auto arr = ArrayReference<BYTE>(byteVector.data(), (unsigned int)byteVector.size());
|
||||
auto arr = ArrayReference<BYTE>(byteVector.data(), static_cast<unsigned int>(byteVector.size()));
|
||||
|
||||
// create a memory stream wrapper
|
||||
InMemoryRandomAccessStream ^ stream = ref new InMemoryRandomAccessStream();
|
||||
|
@ -880,18 +878,7 @@ void Grapher::OnCoreKeyUp(CoreWindow ^ sender, KeyEventArgs ^ e)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (e->VirtualKey)
|
||||
{
|
||||
case VirtualKey::Left:
|
||||
case VirtualKey::Right:
|
||||
case VirtualKey::Down:
|
||||
case VirtualKey::Up:
|
||||
case VirtualKey::Shift:
|
||||
{
|
||||
HandleKey(false, e->VirtualKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
HandleKey(e->VirtualKey);
|
||||
}
|
||||
|
||||
void Grapher::OnCoreKeyDown(CoreWindow ^ sender, KeyEventArgs ^ e)
|
||||
|
@ -904,61 +891,59 @@ void Grapher::OnCoreKeyDown(CoreWindow ^ sender, KeyEventArgs ^ e)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (e->VirtualKey)
|
||||
HandleKeyDown(e->VirtualKey);
|
||||
}
|
||||
|
||||
void Grapher::HandleKey(VirtualKey key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case VirtualKey::Left:
|
||||
m_KeysPressed[KeysPressedSlots::Left] = false;
|
||||
break;
|
||||
case VirtualKey::Right:
|
||||
case VirtualKey::Down:
|
||||
m_KeysPressed[KeysPressedSlots::Right] = false;
|
||||
break;
|
||||
case VirtualKey::Up:
|
||||
m_KeysPressed[KeysPressedSlots::Up] = false;
|
||||
break;
|
||||
case VirtualKey::Down:
|
||||
m_KeysPressed[KeysPressedSlots::Down] = false;
|
||||
break;
|
||||
case VirtualKey::Shift:
|
||||
{
|
||||
HandleKey(true, e->VirtualKey);
|
||||
}
|
||||
m_KeysPressed[KeysPressedSlots::Accelerator] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::HandleKey(bool keyDown, VirtualKey key)
|
||||
void Grapher::HandleKeyDown(VirtualKey key)
|
||||
{
|
||||
int pressedKeys = 0;
|
||||
if (key == VirtualKey::Left)
|
||||
bool pressedKey;
|
||||
switch (key)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Left] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Right)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Right] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Up)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Up] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Down)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Down] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Shift)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Accelerator] = keyDown;
|
||||
case VirtualKey::Left:
|
||||
m_KeysPressed[KeysPressedSlots::Left] = true;
|
||||
pressedKey = true;
|
||||
break;
|
||||
case VirtualKey::Right:
|
||||
m_KeysPressed[KeysPressedSlots::Right] = true;
|
||||
pressedKey = true;
|
||||
break;
|
||||
case VirtualKey::Up:
|
||||
m_KeysPressed[KeysPressedSlots::Up] = true;
|
||||
pressedKey = true;
|
||||
break;
|
||||
case VirtualKey::Down:
|
||||
m_KeysPressed[KeysPressedSlots::Down] = true;
|
||||
pressedKey = true;
|
||||
break;
|
||||
case VirtualKey::Shift:
|
||||
m_KeysPressed[KeysPressedSlots::Accelerator] = true;
|
||||
pressedKey = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pressedKeys > 0 && !m_Moving)
|
||||
if (pressedKey && !m_Moving)
|
||||
{
|
||||
m_Moving = true;
|
||||
// Key(s) we care about, so ensure we are ticking our timer (and that we have one to tick)
|
||||
|
@ -970,7 +955,6 @@ void Grapher::HandleKey(bool keyDown, VirtualKey key)
|
|||
TimeSpan ts;
|
||||
ts.Duration = 100000; // .1 second
|
||||
m_TracingTrackingTimer->Interval = ts;
|
||||
auto i = m_TracingTrackingTimer->Interval;
|
||||
}
|
||||
m_TracingTrackingTimer->Start();
|
||||
}
|
||||
|
@ -979,7 +963,7 @@ void Grapher::HandleKey(bool keyDown, VirtualKey key)
|
|||
void Grapher::HandleTracingMovementTick(Object ^ sender, Object ^ e)
|
||||
{
|
||||
int delta = 5;
|
||||
int liveKeys = 0;
|
||||
bool liveKeys = false;
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Accelerator])
|
||||
{
|
||||
|
@ -990,7 +974,7 @@ void Grapher::HandleTracingMovementTick(Object ^ sender, Object ^ e)
|
|||
|
||||
if (m_KeysPressed[KeysPressedSlots::Left])
|
||||
{
|
||||
liveKeys++;
|
||||
liveKeys = true;
|
||||
curPos.X -= delta;
|
||||
if (curPos.X < 0)
|
||||
{
|
||||
|
@ -998,9 +982,9 @@ void Grapher::HandleTracingMovementTick(Object ^ sender, Object ^ e)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Right])
|
||||
else if (m_KeysPressed[KeysPressedSlots::Right])
|
||||
{
|
||||
liveKeys++;
|
||||
liveKeys = true;
|
||||
curPos.X += delta;
|
||||
if (curPos.X > ActualWidth - delta)
|
||||
{
|
||||
|
@ -1010,7 +994,7 @@ void Grapher::HandleTracingMovementTick(Object ^ sender, Object ^ e)
|
|||
|
||||
if (m_KeysPressed[KeysPressedSlots::Up])
|
||||
{
|
||||
liveKeys++;
|
||||
liveKeys = true;
|
||||
curPos.Y -= delta;
|
||||
if (curPos.Y < 0)
|
||||
{
|
||||
|
@ -1018,9 +1002,9 @@ void Grapher::HandleTracingMovementTick(Object ^ sender, Object ^ e)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Down])
|
||||
else if (m_KeysPressed[KeysPressedSlots::Down])
|
||||
{
|
||||
liveKeys++;
|
||||
liveKeys = true;
|
||||
curPos.Y += delta;
|
||||
if (curPos.Y > ActualHeight - delta)
|
||||
{
|
||||
|
@ -1028,18 +1012,18 @@ void Grapher::HandleTracingMovementTick(Object ^ sender, Object ^ e)
|
|||
}
|
||||
}
|
||||
|
||||
if (liveKeys == 0)
|
||||
if (liveKeys)
|
||||
{
|
||||
ActiveTraceCursorPosition = curPos;
|
||||
PointerValueChangedEvent(curPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Moving = false;
|
||||
|
||||
// Non of the keys we care about are being hit any longer so shut down our timer
|
||||
m_TracingTrackingTimer->Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveTraceCursorPosition = curPos;
|
||||
PointerValueChangedEvent(curPos);
|
||||
}
|
||||
}
|
||||
|
||||
String ^ Grapher::ConvertToLinear(String ^ mmlString)
|
||||
|
@ -1061,7 +1045,7 @@ String ^ Grapher::FormatMathML(String ^ mmlString)
|
|||
return ref new String(formattedExpression.c_str());
|
||||
}
|
||||
|
||||
void Grapher::OnAxesColorPropertyChanged(Windows::UI::Color /*oldValue*/, Windows::UI::Color newValue)
|
||||
void Grapher::OnAxesColorPropertyChanged(Windows::UI::Color oldValue [[maybe_unused]], Windows::UI::Color newValue)
|
||||
{
|
||||
if (m_graph)
|
||||
{
|
||||
|
@ -1071,7 +1055,7 @@ void Grapher::OnAxesColorPropertyChanged(Windows::UI::Color /*oldValue*/, Window
|
|||
}
|
||||
}
|
||||
|
||||
void Grapher::OnGraphBackgroundPropertyChanged(Windows::UI::Color /*oldValue*/, Windows::UI::Color newValue)
|
||||
void Grapher::OnGraphBackgroundPropertyChanged(Windows::UI::Color oldValue [[maybe_unused]], Windows::UI::Color newValue)
|
||||
{
|
||||
if (m_renderMain)
|
||||
{
|
||||
|
@ -1085,7 +1069,7 @@ void Grapher::OnGraphBackgroundPropertyChanged(Windows::UI::Color /*oldValue*/,
|
|||
}
|
||||
}
|
||||
|
||||
void Grapher::OnGridLinesColorPropertyChanged(Windows::UI::Color /*oldValue*/, Windows::UI::Color newValue)
|
||||
void Grapher::OnGridLinesColorPropertyChanged(Windows::UI::Color oldValue [[maybe_unused]], Windows::UI::Color newValue)
|
||||
{
|
||||
if (m_renderMain != nullptr && m_graph != nullptr)
|
||||
{
|
||||
|
|
|
@ -126,7 +126,7 @@ public enum class GraphViewChangedReason
|
|||
{
|
||||
void set(int value)
|
||||
{
|
||||
if (value != (int)m_solver->EvalOptions().GetTrigUnitMode())
|
||||
if (value != static_cast<int>(m_solver->EvalOptions().GetTrigUnitMode()))
|
||||
{
|
||||
m_solver->EvalOptions().SetTrigUnitMode((Graphing::EvalTrigUnitMode)value);
|
||||
m_trigUnitsChanged = true;
|
||||
|
@ -136,7 +136,7 @@ public enum class GraphViewChangedReason
|
|||
|
||||
int get()
|
||||
{
|
||||
return (int)m_solver->EvalOptions().GetTrigUnitMode();
|
||||
return static_cast<int>(m_solver->EvalOptions().GetTrigUnitMode());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,12 +275,12 @@ public enum class GraphViewChangedReason
|
|||
#pragma endregion
|
||||
|
||||
private:
|
||||
void OnForceProportionalAxesPropertyChanged(bool oldValue, bool newValue);
|
||||
void OnForceProportionalAxesPropertyChanged(bool oldValue [[maybe_unused]], bool newValue);
|
||||
void OnUseCommaDecimalSeperatorPropertyChanged(bool oldValue, bool newValue);
|
||||
void OnEquationsPropertyChanged(EquationCollection ^ oldValue, EquationCollection ^ newValue);
|
||||
void OnAxesColorPropertyChanged(Windows::UI::Color oldValue, Windows::UI::Color newValue);
|
||||
void OnGraphBackgroundPropertyChanged(Windows::UI::Color oldValue, Windows::UI::Color newValue);
|
||||
void OnGridLinesColorPropertyChanged(Windows::UI::Color /*oldValue*/, Windows::UI::Color newValue);
|
||||
void OnAxesColorPropertyChanged(Windows::UI::Color oldValue [[maybe_unused]], Windows::UI::Color newValue);
|
||||
void OnGraphBackgroundPropertyChanged(Windows::UI::Color oldValue [[maybe_unused]], Windows::UI::Color newValue);
|
||||
void OnGridLinesColorPropertyChanged(Windows::UI::Color oldValue [[maybe_unused]], Windows::UI::Color newValue);
|
||||
void OnLineWidthPropertyChanged(double oldValue, double newValue);
|
||||
void OnEquationChanged(Equation ^ equation);
|
||||
void OnEquationStyleChanged(Equation ^ equation);
|
||||
|
@ -300,13 +300,13 @@ public enum class GraphViewChangedReason
|
|||
|
||||
void UpdateTracingChanged();
|
||||
void HandleTracingMovementTick(Object ^ sender, Object ^ e);
|
||||
void HandleKey(bool keyDown, Windows::System::VirtualKey key);
|
||||
void HandleKey(Windows::System::VirtualKey key);
|
||||
void HandleKeyDown(Windows::System::VirtualKey key);
|
||||
|
||||
void SetEquationsAsValid();
|
||||
void SetEquationErrors();
|
||||
std::optional<std::vector<std::shared_ptr<Graphing::IEquation>>> TryInitializeGraph(bool keepCurrentView, _In_ const Graphing::IExpression* graphingExp = nullptr);
|
||||
|
||||
|
||||
private:
|
||||
DX::RenderMain ^ m_renderMain = nullptr;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace GraphControl::DX
|
|||
// Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
|
||||
inline float ConvertDipsToPixels(float dips, float dpi)
|
||||
{
|
||||
static const float dipsPerInch = 96.0f;
|
||||
static constexpr float dipsPerInch = 96.0f;
|
||||
return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace GraphControl::DX
|
|||
{
|
||||
if (auto renderer = m_graph->GetRenderer())
|
||||
{
|
||||
float dpi = m_deviceResources.GetDpi();
|
||||
auto dpi = m_deviceResources.GetDpi();
|
||||
renderer->SetDpi(dpi, dpi);
|
||||
|
||||
renderer->SetGraphSize(static_cast<unsigned int>(m_swapChainPanel->ActualWidth), static_cast<unsigned int>(m_swapChainPanel->ActualHeight));
|
||||
|
@ -78,20 +78,24 @@ namespace GraphControl::DX
|
|||
|
||||
void RenderMain::DrawNearestPoint::set(bool value)
|
||||
{
|
||||
if (m_drawNearestPoint != value)
|
||||
if (m_drawNearestPoint == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_drawNearestPoint = value;
|
||||
|
||||
if (!m_drawNearestPoint)
|
||||
{
|
||||
m_Tracing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderMain::PointerLocation::set(Point location)
|
||||
{
|
||||
if (m_pointerLocation != location)
|
||||
if (m_pointerLocation == location)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_pointerLocation = location;
|
||||
|
||||
bool wasPointRendered = m_Tracing;
|
||||
|
@ -100,12 +104,13 @@ namespace GraphControl::DX
|
|||
RunRenderPassAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderMain::ActiveTracing::set(bool value)
|
||||
{
|
||||
if (m_drawActiveTracing != value)
|
||||
if (m_drawActiveTracing == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_drawActiveTracing = value;
|
||||
|
||||
bool wasPointRendered = m_Tracing;
|
||||
|
@ -114,7 +119,6 @@ namespace GraphControl::DX
|
|||
RunRenderPassAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderMain::ActiveTracing::get()
|
||||
{
|
||||
|
@ -232,7 +236,9 @@ namespace GraphControl::DX
|
|||
}
|
||||
|
||||
auto device = m_deviceResources;
|
||||
auto workItemHandler = ref new WorkItemHandler([this, allowCancel](IAsyncAction ^ action) {
|
||||
auto workItemHandler = ref new WorkItemHandler(
|
||||
[this, allowCancel](IAsyncAction ^ action)
|
||||
{
|
||||
critical_section::scoped_lock lock(m_criticalSection);
|
||||
|
||||
// allowCancel is passed as false when the grapher relies on the render pass to validate that an equation can be succesfully rendered.
|
||||
|
@ -277,8 +283,6 @@ namespace GraphControl::DX
|
|||
// Returns true if the frame was rendered and is ready to be displayed.
|
||||
bool RenderMain::Render()
|
||||
{
|
||||
bool successful = true;
|
||||
|
||||
// Must call BeginDraw before any draw commands.
|
||||
ID2D1Factory3* pFactory = m_deviceResources.GetD2DFactory();
|
||||
ID2D1DeviceContext* pRenderTarget = m_deviceResources.GetD2DDeviceContext();
|
||||
|
@ -288,8 +292,13 @@ namespace GraphControl::DX
|
|||
// Clear the back buffer and set the background color.
|
||||
context->ClearRenderTargetView(m_deviceResources.GetBackBufferRenderTargetView(), m_backgroundColor);
|
||||
|
||||
if (m_graph)
|
||||
if (!m_graph)
|
||||
{
|
||||
// Nothing else to render
|
||||
return true;
|
||||
}
|
||||
|
||||
bool successful = true;
|
||||
if (auto renderer = m_graph->GetRenderer())
|
||||
{
|
||||
pRenderTarget->BeginDraw();
|
||||
|
@ -368,8 +377,6 @@ namespace GraphControl::DX
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
|
@ -473,10 +480,12 @@ namespace GraphControl::DX
|
|||
|
||||
void RenderMain::OnVisibilityChanged(CoreWindow ^ sender, VisibilityChangedEventArgs ^ args)
|
||||
{
|
||||
if (args->Visible)
|
||||
if (!args->Visible)
|
||||
{
|
||||
RunRenderPass();
|
||||
return;
|
||||
}
|
||||
|
||||
RunRenderPass();
|
||||
}
|
||||
|
||||
void RenderMain::OnDpiChanged(DisplayInformation ^ sender, Object ^ args)
|
||||
|
@ -491,7 +500,7 @@ namespace GraphControl::DX
|
|||
{
|
||||
if (auto renderer = m_graph->GetRenderer())
|
||||
{
|
||||
float dpi = m_deviceResources.GetDpi();
|
||||
auto dpi = m_deviceResources.GetDpi();
|
||||
renderer->SetDpi(dpi, dpi);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace GraphControl
|
|||
return s_selfInstance;
|
||||
}
|
||||
|
||||
void TraceLogger::LogEquationCountChanged(int currentValidEquations, int currentInvalidEquations)
|
||||
void TraceLogger::LogEquationCountChanged(unsigned int currentValidEquations, unsigned int currentInvalidEquations)
|
||||
{
|
||||
static bool firstRun = true;
|
||||
if (firstRun)
|
||||
|
@ -80,11 +80,11 @@ namespace GraphControl
|
|||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_FUNCTION_ANALYSIS_PERFORMED), fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogVariableCountChanged(int variablesCount)
|
||||
void TraceLogger::LogVariableCountChanged(unsigned int variablesCount)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), StringReference(GRAPHING_MODE));
|
||||
fields->AddInt64(StringReference(L"VariableCount"), variablesCount);
|
||||
fields->AddUInt64(StringReference(L"VariableCount"), variablesCount);
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_VARIABLES_COUNT_CHANGED), fields);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ namespace GraphControl
|
|||
internal:
|
||||
static TraceLogger ^ GetInstance();
|
||||
|
||||
void LogEquationCountChanged(int currentValidEquations, int currentInvalidEquations);
|
||||
void LogEquationCountChanged(unsigned int currentValidEquations, unsigned int currentInvalidEquations);
|
||||
void LogFunctionAnalysisPerformed(int analysisErrorType, uint32 tooComplexFlag);
|
||||
void LogVariableCountChanged(int variablesCount);
|
||||
void LogVariableCountChanged(unsigned int variablesCount);
|
||||
void LogLineWidthChanged();
|
||||
|
||||
private:
|
||||
|
|
|
@ -180,7 +180,7 @@ namespace Utils
|
|||
template <typename T>
|
||||
struct IsRefClass
|
||||
{
|
||||
static const bool value = __is_ref_class(T);
|
||||
static constexpr bool value = __is_ref_class(T);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace MockGraphingImpl
|
|||
{
|
||||
class Bitmap : public Graphing::IBitmap
|
||||
{
|
||||
virtual const std::vector<BYTE>& GetData() const
|
||||
const std::vector<BYTE>& GetData() const override
|
||||
{
|
||||
return std::vector<BYTE>();
|
||||
}
|
||||
|
|
|
@ -16,49 +16,50 @@ namespace MockGraphingImpl
|
|||
{
|
||||
m_graphRenderer = std::make_shared<GraphRenderer>();
|
||||
}
|
||||
virtual std::optional<std::vector<std::shared_ptr<Graphing::IEquation>>> TryInitialize(const Graphing::IExpression* graphingExp = nullptr)
|
||||
|
||||
std::optional<std::vector<std::shared_ptr<Graphing::IEquation>>> TryInitialize(const Graphing::IExpression* graphingExp = nullptr) override
|
||||
{
|
||||
if (graphingExp != nullptr)
|
||||
{
|
||||
std::vector<std::shared_ptr<Graphing::IEquation>> equations;
|
||||
equations.push_back(nullptr);
|
||||
m_variables.push_back(std::make_shared<MockVariable>(MockVariable{}));
|
||||
return std::optional<std::vector<std::shared_ptr<Graphing::IEquation>>>(equations);
|
||||
return std::optional(equations);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
HRESULT GetInitializationError()
|
||||
HRESULT GetInitializationError() override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual Graphing::IGraphingOptions& GetOptions()
|
||||
Graphing::IGraphingOptions& GetOptions() override
|
||||
{
|
||||
return m_graphingOptions;
|
||||
}
|
||||
|
||||
virtual std::vector<std::shared_ptr<Graphing::IVariable>> GetVariables()
|
||||
std::vector<std::shared_ptr<Graphing::IVariable>> GetVariables() override
|
||||
{
|
||||
return m_variables;
|
||||
}
|
||||
|
||||
virtual void SetArgValue(std::wstring variableName, double value)
|
||||
void SetArgValue(std::wstring variableName, double value) override
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<Graphing::Renderer::IGraphRenderer> GetRenderer() const
|
||||
std::shared_ptr<Graphing::Renderer::IGraphRenderer> GetRenderer() const override
|
||||
{
|
||||
return m_graphRenderer;
|
||||
}
|
||||
|
||||
virtual bool TryResetSelection()
|
||||
bool TryResetSelection() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<Graphing::Analyzer::IGraphAnalyzer> GetAnalyzer() const
|
||||
std::shared_ptr<Graphing::Analyzer::IGraphAnalyzer> GetAnalyzer() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -22,22 +22,23 @@ namespace MockGraphingImpl
|
|||
{
|
||||
}
|
||||
|
||||
virtual HRESULT SetGraphSize(unsigned int width, unsigned int height)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT SetDpi(float dpiX, float dpiY)
|
||||
HRESULT SetGraphSize(unsigned int width, unsigned int height) override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT DrawD2D1(ID2D1Factory* pDirect2dFactory, ID2D1RenderTarget* pRenderTarget, bool& hasSomeMissingDataOut)
|
||||
HRESULT SetDpi(float dpiX, float dpiY) override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DrawD2D1(ID2D1Factory* pDirect2dFactory, ID2D1RenderTarget* pRenderTarget, bool& hasSomeMissingDataOut) override
|
||||
{
|
||||
hasSomeMissingDataOut = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT GetClosePointData(
|
||||
HRESULT GetClosePointData(
|
||||
double inScreenPointX,
|
||||
double inScreenPointY,
|
||||
double precision,
|
||||
|
@ -48,7 +49,7 @@ namespace MockGraphingImpl
|
|||
double& yValueOut,
|
||||
double& rhoValueOut,
|
||||
double& thetaValueOut,
|
||||
double& tValueOut)
|
||||
double& tValueOut) override
|
||||
{
|
||||
formulaIdOut = 0;
|
||||
xScreenPointOut = 0;
|
||||
|
@ -59,7 +60,7 @@ namespace MockGraphingImpl
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT ScaleRange(double centerX, double centerY, double scale)
|
||||
HRESULT ScaleRange(double centerX, double centerY, double scale) override
|
||||
{
|
||||
m_xMin = scale * (m_xMin - centerX) + centerX;
|
||||
m_xMax = scale * (m_xMax - centerX) + centerX;
|
||||
|
@ -68,19 +69,22 @@ namespace MockGraphingImpl
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT ChangeRange(Graphing::Renderer::ChangeRangeAction action)
|
||||
HRESULT ChangeRange(Graphing::Renderer::ChangeRangeAction action) override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT MoveRangeByRatio(double ratioX, double ratioY)
|
||||
|
||||
HRESULT MoveRangeByRatio(double ratioX, double ratioY) override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT ResetRange()
|
||||
|
||||
HRESULT ResetRange() override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT GetDisplayRanges(double& xMin, double& xMax, double& yMin, double& yMax)
|
||||
|
||||
HRESULT GetDisplayRanges(double& xMin, double& xMax, double& yMin, double& yMax) override
|
||||
{
|
||||
xMin = m_xMin;
|
||||
xMax = m_xMax;
|
||||
|
@ -88,7 +92,8 @@ namespace MockGraphingImpl
|
|||
yMax = m_yMax;
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT SetDisplayRanges(double xMin, double xMax, double yMin, double yMax)
|
||||
|
||||
HRESULT SetDisplayRanges(double xMin, double xMax, double yMin, double yMax) override
|
||||
{
|
||||
m_xMin = xMin;
|
||||
m_xMax = xMax;
|
||||
|
@ -97,12 +102,12 @@ namespace MockGraphingImpl
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT PrepareGraph()
|
||||
HRESULT PrepareGraph() override
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT GetBitmap(std::shared_ptr<Graphing::IBitmap>& bitmapOut, bool& hasSomeMissingDataOut)
|
||||
HRESULT GetBitmap(std::shared_ptr<Graphing::IBitmap>& bitmapOut, bool& hasSomeMissingDataOut) override
|
||||
{
|
||||
bitmapOut = std::make_shared<Bitmap>();
|
||||
hasSomeMissingDataOut = false;
|
||||
|
|
|
@ -20,17 +20,7 @@ namespace MockGraphingImpl
|
|||
, m_markHorizontalAsymptotes(false)
|
||||
, m_markObliqueAsymptotes(false)
|
||||
, m_maxExecutionTime(0)
|
||||
, m_colors()
|
||||
, m_backColor()
|
||||
, m_allowKeyGraphFeaturesForFunctionsWithParameters(false)
|
||||
, m_zerosColor()
|
||||
, m_extremaColor()
|
||||
, m_inflectionPointsColor()
|
||||
, m_asymptotesColor()
|
||||
, m_axisColor()
|
||||
, m_boxColor()
|
||||
, m_gridColor()
|
||||
, m_fontColor()
|
||||
, m_showAxis(true)
|
||||
, m_showGrid(true)
|
||||
, m_showBox(true)
|
||||
|
@ -43,358 +33,404 @@ namespace MockGraphingImpl
|
|||
{
|
||||
}
|
||||
|
||||
virtual void ResetMarkKeyGraphFeaturesData()
|
||||
void ResetMarkKeyGraphFeaturesData() override
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool GetMarkZeros() const
|
||||
bool GetMarkZeros() const override
|
||||
{
|
||||
return m_markZeros;
|
||||
}
|
||||
virtual void SetMarkZeros(bool value)
|
||||
|
||||
void SetMarkZeros(bool value) override
|
||||
{
|
||||
m_markZeros = value;
|
||||
}
|
||||
|
||||
virtual bool GetMarkYIntercept() const
|
||||
bool GetMarkYIntercept() const override
|
||||
{
|
||||
return m_markYIntercept;
|
||||
}
|
||||
virtual void SetMarkYIntercept(bool value)
|
||||
|
||||
void SetMarkYIntercept(bool value) override
|
||||
{
|
||||
m_markYIntercept = value;
|
||||
}
|
||||
|
||||
virtual bool GetMarkMinima() const
|
||||
bool GetMarkMinima() const override
|
||||
{
|
||||
return m_markMinima;
|
||||
}
|
||||
virtual void SetMarkMinima(bool value)
|
||||
|
||||
void SetMarkMinima(bool value) override
|
||||
{
|
||||
m_markMinima = value;
|
||||
}
|
||||
|
||||
virtual bool GetMarkMaxima() const
|
||||
bool GetMarkMaxima() const override
|
||||
{
|
||||
return m_markMaxima;
|
||||
}
|
||||
virtual void SetMarkMaxima(bool value)
|
||||
|
||||
void SetMarkMaxima(bool value) override
|
||||
{
|
||||
m_markMaxima = value;
|
||||
}
|
||||
|
||||
virtual bool GetMarkInflectionPoints() const
|
||||
bool GetMarkInflectionPoints() const override
|
||||
{
|
||||
return m_markInflectionPoints;
|
||||
}
|
||||
virtual void SetMarkInflectionPoints(bool value)
|
||||
|
||||
void SetMarkInflectionPoints(bool value) override
|
||||
{
|
||||
m_markInflectionPoints = value;
|
||||
}
|
||||
|
||||
virtual bool GetMarkVerticalAsymptotes() const
|
||||
bool GetMarkVerticalAsymptotes() const override
|
||||
{
|
||||
return m_markVerticalAsymptotes;
|
||||
}
|
||||
virtual void SetMarkVerticalAsymptotes(bool value)
|
||||
|
||||
void SetMarkVerticalAsymptotes(bool value) override
|
||||
{
|
||||
m_markVerticalAsymptotes = value;
|
||||
}
|
||||
|
||||
virtual bool GetMarkHorizontalAsymptotes() const
|
||||
bool GetMarkHorizontalAsymptotes() const override
|
||||
{
|
||||
return m_markHorizontalAsymptotes;
|
||||
}
|
||||
virtual void SetMarkHorizontalAsymptotes(bool value)
|
||||
|
||||
void SetMarkHorizontalAsymptotes(bool value) override
|
||||
{
|
||||
m_markHorizontalAsymptotes = value;
|
||||
}
|
||||
|
||||
virtual bool GetMarkObliqueAsymptotes() const
|
||||
bool GetMarkObliqueAsymptotes() const override
|
||||
{
|
||||
return m_markObliqueAsymptotes;
|
||||
}
|
||||
virtual void SetMarkObliqueAsymptotes(bool value)
|
||||
|
||||
void SetMarkObliqueAsymptotes(bool value) override
|
||||
{
|
||||
m_markObliqueAsymptotes = value;
|
||||
}
|
||||
|
||||
virtual unsigned long long GetMaxExecutionTime() const
|
||||
unsigned long long GetMaxExecutionTime() const override
|
||||
{
|
||||
return m_maxExecutionTime;
|
||||
}
|
||||
virtual void SetMaxExecutionTime(unsigned long long value)
|
||||
|
||||
void SetMaxExecutionTime(unsigned long long value) override
|
||||
{
|
||||
m_maxExecutionTime = value;
|
||||
}
|
||||
|
||||
virtual void ResetMaxExecutionTime()
|
||||
void ResetMaxExecutionTime() override
|
||||
{
|
||||
m_maxExecutionTime = 0;
|
||||
};
|
||||
}
|
||||
|
||||
virtual std::vector<Graphing::Color> GetGraphColors() const
|
||||
std::vector<Graphing::Color> GetGraphColors() const override
|
||||
{
|
||||
return m_colors;
|
||||
}
|
||||
virtual bool SetGraphColors(const std::vector<Graphing::Color>& colors)
|
||||
|
||||
bool SetGraphColors(const std::vector<Graphing::Color>& colors) override
|
||||
{
|
||||
m_colors = colors;
|
||||
return true;
|
||||
}
|
||||
virtual void ResetGraphColors()
|
||||
|
||||
void ResetGraphColors() override
|
||||
{
|
||||
m_colors.clear();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetBackColor() const
|
||||
Graphing::Color GetBackColor() const override
|
||||
{
|
||||
return m_backColor;
|
||||
}
|
||||
virtual void SetBackColor(const Graphing::Color& value)
|
||||
|
||||
void SetBackColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_backColor = value;
|
||||
}
|
||||
|
||||
virtual void ResetBackColor()
|
||||
void ResetBackColor() override
|
||||
{
|
||||
m_backColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual void SetAllowKeyGraphFeaturesForFunctionsWithParameters(bool kgf)
|
||||
void SetAllowKeyGraphFeaturesForFunctionsWithParameters(bool kgf) override
|
||||
{
|
||||
m_allowKeyGraphFeaturesForFunctionsWithParameters = kgf;
|
||||
}
|
||||
virtual bool GetAllowKeyGraphFeaturesForFunctionsWithParameters() const
|
||||
|
||||
bool GetAllowKeyGraphFeaturesForFunctionsWithParameters() const override
|
||||
{
|
||||
return m_allowKeyGraphFeaturesForFunctionsWithParameters;
|
||||
}
|
||||
virtual void ResetAllowKeyGraphFeaturesForFunctionsWithParameters()
|
||||
|
||||
void ResetAllowKeyGraphFeaturesForFunctionsWithParameters() override
|
||||
{
|
||||
m_allowKeyGraphFeaturesForFunctionsWithParameters = true;
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetZerosColor() const
|
||||
Graphing::Color GetZerosColor() const override
|
||||
{
|
||||
return m_zerosColor;
|
||||
}
|
||||
virtual void SetZerosColor(const Graphing::Color& value)
|
||||
|
||||
void SetZerosColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_zerosColor = value;
|
||||
}
|
||||
virtual void ResetZerosColor()
|
||||
|
||||
void ResetZerosColor() override
|
||||
{
|
||||
m_zerosColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetExtremaColor() const
|
||||
Graphing::Color GetExtremaColor() const override
|
||||
{
|
||||
return m_extremaColor;
|
||||
}
|
||||
virtual void SetExtremaColor(const Graphing::Color& value)
|
||||
|
||||
void SetExtremaColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_extremaColor = value;
|
||||
}
|
||||
virtual void ResetExtremaColor()
|
||||
|
||||
void ResetExtremaColor() override
|
||||
{
|
||||
m_extremaColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetInflectionPointsColor() const
|
||||
Graphing::Color GetInflectionPointsColor() const override
|
||||
{
|
||||
return m_inflectionPointsColor;
|
||||
}
|
||||
virtual void SetInflectionPointsColor(const Graphing::Color& value)
|
||||
|
||||
void SetInflectionPointsColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_inflectionPointsColor = value;
|
||||
}
|
||||
virtual void ResetInflectionPointsColor()
|
||||
|
||||
void ResetInflectionPointsColor() override
|
||||
{
|
||||
m_inflectionPointsColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetAsymptotesColor() const
|
||||
Graphing::Color GetAsymptotesColor() const override
|
||||
{
|
||||
return m_asymptotesColor;
|
||||
}
|
||||
virtual void SetAsymptotesColor(const Graphing::Color& value)
|
||||
|
||||
void SetAsymptotesColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_asymptotesColor = value;
|
||||
}
|
||||
virtual void ResetAsymptotesColor()
|
||||
|
||||
void ResetAsymptotesColor() override
|
||||
{
|
||||
m_asymptotesColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetAxisColor() const
|
||||
Graphing::Color GetAxisColor() const override
|
||||
{
|
||||
return m_axisColor;
|
||||
}
|
||||
virtual void SetAxisColor(const Graphing::Color& value)
|
||||
|
||||
void SetAxisColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_axisColor = value;
|
||||
}
|
||||
virtual void ResetAxisColor()
|
||||
|
||||
void ResetAxisColor() override
|
||||
{
|
||||
m_axisColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetBoxColor() const
|
||||
Graphing::Color GetBoxColor() const override
|
||||
{
|
||||
return m_boxColor;
|
||||
}
|
||||
virtual void SetBoxColor(const Graphing::Color& value)
|
||||
|
||||
void SetBoxColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_boxColor = value;
|
||||
}
|
||||
virtual void ResetBoxColor()
|
||||
|
||||
void ResetBoxColor() override
|
||||
{
|
||||
m_boxColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetGridColor() const
|
||||
Graphing::Color GetGridColor() const override
|
||||
{
|
||||
return m_gridColor;
|
||||
}
|
||||
virtual void SetGridColor(const Graphing::Color& value)
|
||||
|
||||
void SetGridColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_gridColor = value;
|
||||
}
|
||||
virtual void ResetGridColor()
|
||||
|
||||
void ResetGridColor() override
|
||||
{
|
||||
m_gridColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual Graphing::Color GetFontColor() const
|
||||
Graphing::Color GetFontColor() const override
|
||||
{
|
||||
return m_fontColor;
|
||||
}
|
||||
virtual void SetFontColor(const Graphing::Color& value)
|
||||
|
||||
void SetFontColor(const Graphing::Color& value) override
|
||||
{
|
||||
m_fontColor = value;
|
||||
}
|
||||
virtual void ResetFontColor()
|
||||
|
||||
void ResetFontColor() override
|
||||
{
|
||||
m_fontColor = Graphing::Color();
|
||||
}
|
||||
|
||||
virtual bool GetShowAxis() const
|
||||
bool GetShowAxis() const override
|
||||
{
|
||||
return m_showAxis;
|
||||
}
|
||||
virtual void SetShowAxis(bool value)
|
||||
|
||||
void SetShowAxis(bool value) override
|
||||
{
|
||||
m_showAxis = value;
|
||||
}
|
||||
virtual void ResetShowAxis()
|
||||
|
||||
void ResetShowAxis() override
|
||||
{
|
||||
m_showAxis = true;
|
||||
}
|
||||
|
||||
virtual bool GetShowGrid() const
|
||||
bool GetShowGrid() const override
|
||||
{
|
||||
return m_showGrid;
|
||||
}
|
||||
virtual void SetShowGrid(bool value)
|
||||
|
||||
void SetShowGrid(bool value) override
|
||||
{
|
||||
m_showGrid = value;
|
||||
}
|
||||
virtual void ResetShowGrid()
|
||||
|
||||
void ResetShowGrid() override
|
||||
{
|
||||
m_showGrid = true;
|
||||
}
|
||||
|
||||
virtual bool GetShowBox() const
|
||||
bool GetShowBox() const override
|
||||
{
|
||||
return m_showBox;
|
||||
}
|
||||
virtual void SetShowBox(bool value)
|
||||
|
||||
void SetShowBox(bool value) override
|
||||
{
|
||||
m_showBox = value;
|
||||
}
|
||||
virtual void ResetShowBox()
|
||||
|
||||
void ResetShowBox() override
|
||||
{
|
||||
m_showBox = true;
|
||||
}
|
||||
|
||||
virtual bool GetForceProportional() const
|
||||
bool GetForceProportional() const override
|
||||
{
|
||||
return m_forceProportional;
|
||||
}
|
||||
virtual void SetForceProportional(bool value)
|
||||
|
||||
void SetForceProportional(bool value) override
|
||||
{
|
||||
m_forceProportional = value;
|
||||
}
|
||||
virtual void ResetForceProportional()
|
||||
|
||||
void ResetForceProportional() override
|
||||
{
|
||||
m_forceProportional = false;
|
||||
}
|
||||
|
||||
virtual std::wstring GetAliasX() const
|
||||
std::wstring GetAliasX() const override
|
||||
{
|
||||
return m_aliasX;
|
||||
}
|
||||
virtual void SetAliasX(const std::wstring& value)
|
||||
|
||||
void SetAliasX(const std::wstring& value) override
|
||||
{
|
||||
m_aliasX = value;
|
||||
}
|
||||
virtual void ResetAliasX()
|
||||
|
||||
void ResetAliasX() override
|
||||
{
|
||||
m_aliasX = L"";
|
||||
}
|
||||
|
||||
virtual std::wstring GetAliasY() const
|
||||
std::wstring GetAliasY() const override
|
||||
{
|
||||
return m_aliasY;
|
||||
}
|
||||
virtual void SetAliasY(const std::wstring& value)
|
||||
|
||||
void SetAliasY(const std::wstring& value) override
|
||||
{
|
||||
m_aliasY = value;
|
||||
}
|
||||
virtual void ResetAliasY()
|
||||
|
||||
void ResetAliasY() override
|
||||
{
|
||||
m_aliasY = L"";
|
||||
}
|
||||
|
||||
virtual Graphing::Renderer::LineStyle GetLineStyle() const
|
||||
Graphing::Renderer::LineStyle GetLineStyle() const override
|
||||
{
|
||||
return m_lineStyle;
|
||||
}
|
||||
virtual void SetLineStyle(Graphing::Renderer::LineStyle value)
|
||||
|
||||
void SetLineStyle(Graphing::Renderer::LineStyle value) override
|
||||
{
|
||||
m_lineStyle = value;
|
||||
}
|
||||
virtual void ResetLineStyle()
|
||||
|
||||
void ResetLineStyle() override
|
||||
{
|
||||
m_lineStyle = Graphing::Renderer::LineStyle::Solid;
|
||||
}
|
||||
|
||||
virtual std::pair<double, double> GetDefaultXRange() const
|
||||
std::pair<double, double> GetDefaultXRange() const override
|
||||
{
|
||||
return m_XRange;
|
||||
}
|
||||
|
||||
virtual bool SetDefaultXRange(const std::pair<double, double>& minmax)
|
||||
bool SetDefaultXRange(const std::pair<double, double>& minmax) override
|
||||
{
|
||||
m_XRange = minmax;
|
||||
return true;
|
||||
}
|
||||
virtual void ResetDefaultXRange()
|
||||
|
||||
void ResetDefaultXRange() override
|
||||
{
|
||||
m_XRange = { 0, 0 };
|
||||
}
|
||||
|
||||
virtual std::pair<double, double> GetDefaultYRange() const
|
||||
std::pair<double, double> GetDefaultYRange() const override
|
||||
{
|
||||
return m_YRange;
|
||||
}
|
||||
|
||||
virtual bool SetDefaultYRange(const std::pair<double, double>& minmax)
|
||||
bool SetDefaultYRange(const std::pair<double, double>& minmax) override
|
||||
{
|
||||
m_YRange = minmax;
|
||||
return true;
|
||||
}
|
||||
virtual void ResetDefaultYRange()
|
||||
|
||||
void ResetDefaultYRange() override
|
||||
{
|
||||
m_YRange = { 0, 0 };
|
||||
}
|
||||
|
|
|
@ -59,15 +59,13 @@ namespace MockGraphingImpl
|
|||
class MockExpression : public Graphing::IExpression
|
||||
{
|
||||
public:
|
||||
MockExpression()
|
||||
{
|
||||
}
|
||||
MockExpression() = default;
|
||||
|
||||
unsigned int GetExpressionID() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bool IsEmptySet() const
|
||||
bool IsEmptySet() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -76,9 +74,7 @@ namespace MockGraphingImpl
|
|||
class MockVariable : public Graphing::IVariable
|
||||
{
|
||||
public:
|
||||
MockVariable()
|
||||
{
|
||||
}
|
||||
MockVariable() = default;
|
||||
|
||||
int GetVariableID() const override
|
||||
{
|
||||
|
@ -96,9 +92,7 @@ namespace MockGraphingImpl
|
|||
class MathSolver : public Graphing::IMathSolver
|
||||
{
|
||||
public:
|
||||
MathSolver()
|
||||
{
|
||||
}
|
||||
MathSolver() = default;
|
||||
|
||||
Graphing::IParsingOptions& ParsingOptions() override
|
||||
{
|
||||
|
@ -125,7 +119,7 @@ namespace MockGraphingImpl
|
|||
return std::make_unique<MockExpression>(MockExpression{});
|
||||
}
|
||||
|
||||
void HRErrorToErrorInfo(HRESULT hr, int& errorCodeOut, int& errorTypeOut)
|
||||
void HRErrorToErrorInfo(HRESULT hr, int& errorCodeOut, int& errorTypeOut) override
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -138,7 +132,7 @@ namespace MockGraphingImpl
|
|||
return L"";
|
||||
}
|
||||
|
||||
Graphing::IGraphFunctionAnalysisData IMathSolver::Analyze(const Graphing::Analyzer::IGraphAnalyzer* analyzer)
|
||||
Graphing::IGraphFunctionAnalysisData IMathSolver::Analyze(const Graphing::Analyzer::IGraphAnalyzer* analyzer) override
|
||||
{
|
||||
return Graphing::IGraphFunctionAnalysisData{};
|
||||
}
|
||||
|
|
|
@ -75,34 +75,34 @@ namespace Graphing
|
|||
uint8_t A;
|
||||
|
||||
constexpr Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
|
||||
: R{ r }, G{ g }, B{ b }, A{ a }
|
||||
{}
|
||||
: R{ r }
|
||||
, G{ g }
|
||||
, B{ b }
|
||||
, A{ a }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Color(uint8_t r, uint8_t g, uint8_t b) noexcept
|
||||
: Color{ r, g, b, 0xFF }
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Color() noexcept
|
||||
: Color{ 0, 0, 0 }
|
||||
{}
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
constexpr explicit Color(uint32_t value) noexcept
|
||||
: Color{
|
||||
static_cast<uint8_t>(value >> redChannelShift),
|
||||
: Color{ static_cast<uint8_t>(value >> redChannelShift),
|
||||
static_cast<uint8_t>(value >> greenChannelShift),
|
||||
static_cast<uint8_t>(value >> blueChannelShift),
|
||||
static_cast<uint8_t>(value >> alphaChannelShift)
|
||||
}
|
||||
static_cast<uint8_t>(value >> alphaChannelShift) }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr explicit operator uint32_t() const
|
||||
{
|
||||
return (A << alphaChannelShift)
|
||||
| (R << redChannelShift)
|
||||
| (G << greenChannelShift)
|
||||
| (B << blueChannelShift);
|
||||
return (A << alphaChannelShift) | (R << redChannelShift) | (G << greenChannelShift) | (B << blueChannelShift);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Graphing
|
|||
{
|
||||
struct IEquation : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IEquation() = default;
|
||||
~IEquation() override = default;
|
||||
|
||||
virtual std::shared_ptr<IEquationOptions> GetGraphEquationOptions() const = 0;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Graphing
|
|||
{
|
||||
struct IEquationOptions : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IEquationOptions() = default;
|
||||
~IEquationOptions() override = default;
|
||||
|
||||
virtual Graphing::Color GetGraphColor() const = 0;
|
||||
virtual void SetGraphColor(const Graphing::Color& color) = 0;
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Graphing
|
|||
{
|
||||
struct IGraph : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IGraph() = default;
|
||||
~IGraph() override = default;
|
||||
|
||||
virtual std::optional<std::vector<std::shared_ptr<IEquation>>> TryInitialize(const IExpression* graphingExp = nullptr) = 0;
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
|
||||
namespace Graphing::Analyzer
|
||||
{
|
||||
typedef unsigned int NativeAnalysisType; // PerformAnalysisType
|
||||
using NativeAnalysisType = unsigned int; // PerformAnalysisType
|
||||
|
||||
struct IGraphAnalyzer : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IGraphAnalyzer() = default;
|
||||
~IGraphAnalyzer() override = default;
|
||||
virtual bool CanFunctionAnalysisBePerformed(bool& variableIsNotX) = 0;
|
||||
virtual HRESULT PerformFunctionAnalysis(NativeAnalysisType analysisType) = 0;
|
||||
virtual HRESULT GetAnalysisTypeCaption(const AnalysisType type, std::wstring& captionOut) const = 0;
|
||||
virtual HRESULT GetMessage(const GraphAnalyzerMessage msg, std::wstring& msgOut) const = 0;
|
||||
virtual HRESULT GetAnalysisTypeCaption(AnalysisType type, std::wstring& captionOut) const = 0;
|
||||
virtual HRESULT GetMessage(GraphAnalyzerMessage msg, std::wstring& msgOut) const = 0;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Graphing::Renderer
|
|||
{
|
||||
struct IGraphRenderer : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IGraphRenderer() = default;
|
||||
~IGraphRenderer() override = default;
|
||||
|
||||
virtual HRESULT SetGraphSize(unsigned int width, unsigned int height) = 0;
|
||||
virtual HRESULT SetDpi(float dpiX, float dpiY) = 0;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Graphing
|
|||
{
|
||||
struct IGraphingOptions : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IGraphingOptions() = default;
|
||||
~IGraphingOptions() override = default;
|
||||
|
||||
virtual void ResetMarkKeyGraphFeaturesData() = 0;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Graphing
|
|||
|
||||
struct IParsingOptions : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IParsingOptions() = default;
|
||||
~IParsingOptions() override = default;
|
||||
|
||||
virtual void SetFormatType(FormatType type) = 0;
|
||||
virtual void SetLocalizationType(LocalizationType value) = 0;
|
||||
|
@ -39,7 +39,7 @@ namespace Graphing
|
|||
|
||||
struct IEvalOptions : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IEvalOptions() = default;
|
||||
~IEvalOptions() override = default;
|
||||
|
||||
virtual EvalTrigUnitMode GetTrigUnitMode() const = 0;
|
||||
virtual void SetTrigUnitMode(EvalTrigUnitMode value) = 0;
|
||||
|
@ -47,7 +47,7 @@ namespace Graphing
|
|||
|
||||
struct IFormatOptions : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IFormatOptions() = default;
|
||||
~IFormatOptions() override = default;
|
||||
|
||||
virtual void SetFormatType(FormatType type) = 0;
|
||||
virtual void SetMathMLPrefix(const std::wstring& value) = 0;
|
||||
|
@ -56,7 +56,7 @@ namespace Graphing
|
|||
|
||||
struct IMathSolver : public NonCopyable, public NonMoveable
|
||||
{
|
||||
virtual ~IMathSolver() = default;
|
||||
~IMathSolver() override = default;
|
||||
|
||||
static GRAPHINGAPI std::unique_ptr<IMathSolver> CreateMathSolver();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue