Merge remote-tracking branch 'upstream/master' into Fix245

This commit is contained in:
Rudy Huyn 2019-03-18 16:39:28 -07:00
commit 9a20bac167
300 changed files with 1293 additions and 1055 deletions

View file

@ -5,7 +5,6 @@ root = true
[*] [*]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
end_of_line = crlf
charset = utf-8 charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true

View file

@ -2,7 +2,7 @@
The Windows Calculator app is a modern Windows app written in C++ that ships pre-installed with Windows. The Windows Calculator app is a modern Windows app written in C++ that ships pre-installed with Windows.
The app provides standard, scientific, and programmer calculator functionality, as well as a set of converters between various units of measurement and currencies. The app provides standard, scientific, and programmer calculator functionality, as well as a set of converters between various units of measurement and currencies.
Calculator ships regularly with new features and bug fixes. You can get the latest version of Calculator in the [Microsoft Store.](https://www.microsoft.com/store/apps/9WZDNCRFHVN5) Calculator ships regularly with new features and bug fixes. You can get the latest version of Calculator in the [Microsoft Store](https://www.microsoft.com/store/apps/9WZDNCRFHVN5).
[![Build Status](https://dev.azure.com/ms/calculator/_apis/build/status/Calculator-CI?branchName=master)](https://dev.azure.com/ms/calculator/_build/latest?definitionId=57&branchName=master) [![Build Status](https://dev.azure.com/ms/calculator/_apis/build/status/Calculator-CI?branchName=master)](https://dev.azure.com/ms/calculator/_build/latest?definitionId=57&branchName=master)
@ -18,14 +18,14 @@ Calculator ships regularly with new features and bug fixes. You can get the late
## Getting started ## Getting started
Prerequisites: Prerequisites:
- Your computer must be running Windows 10, version 1803 or newer - Your computer must be running Windows 10, version 1803 or newer.
- Install the latest version of [Visual Studio](https://developer.microsoft.com/en-us/windows/downloads) (the free community edition is sufficient) - Install the latest version of [Visual Studio](https://developer.microsoft.com/en-us/windows/downloads) (the free community edition is sufficient).
- Install the "Universal Windows Platform Development" workload - Install the "Universal Windows Platform Development" workload.
- Install the optional "C++ Universal Windows Platform tools" component - Install the optional "C++ Universal Windows Platform tools" component.
- Install the latest Windows 10 SDK - Install the latest Windows 10 SDK.
![Visual Studio Installation Screenshot](docs/Images/VSInstallationScreenshot.png) ![Visual Studio Installation Screenshot](docs/Images/VSInstallationScreenshot.png)
- Install the [XAML Styler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension - Install the [XAML Styler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension.
- Get the code: - Get the code:
``` ```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

Before After
Before After

View file

@ -11,9 +11,6 @@ namespace Calculator.UIAutomationLibrary.Components
/// <summary> /// <summary>
/// Physical Object Model for the app window. /// Physical Object Model for the app window.
/// POM is the implementation model of the app. /// POM is the implementation model of the app.
/// See following references to POM:
/// * https://blogs.msdn.microsoft.com/wltester/2011/11/14/object-model-design/
/// * https://blogs.msdn.microsoft.com/micahel/2005/06/03/how-do-i-invoke-thee-let-me-count-the-ways-the-physical-object-model/
/// See https://en.wikipedia.org/wiki/Model-based_testing for model-based testing. /// See https://en.wikipedia.org/wiki/Model-based_testing for model-based testing.
/// </summary> /// </summary>
public class MainPagePom : UIObject public class MainPagePom : UIObject

View file

@ -261,7 +261,7 @@ void CalcInput::SetDecimalSymbol(wchar_t decSymbol)
} }
} }
wstring CalcInput::ToString(uint32_t radix, bool isIntegerMode) wstring CalcInput::ToString(uint32_t radix)
{ {
// In theory both the base and exponent could be C_NUM_MAX_DIGITS long. // In theory both the base and exponent could be C_NUM_MAX_DIGITS long.
wstringstream resStream; wstringstream resStream;

View file

@ -3,6 +3,7 @@
#include "pch.h" #include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h"
bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y) bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y)
{ {

View file

@ -2,18 +2,25 @@
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
#pragma once
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Command.h" #include "Command.h"
#include "CalculatorVector.h" #include "CalculatorVector.h"
#include "ExpressionCommand.h" #include "ExpressionCommand.h"
#include "CalcException.h"
constexpr int ASCII_0 = 48; constexpr int ASCII_0 = 48;
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
namespace {
void IFT(HRESULT hr)
{
if (FAILED(hr))
{
throw hr;
}
}
}
void CHistoryCollector::ReinitHistory() void CHistoryCollector::ReinitHistory()
{ {
m_lastOpStartIndex = -1; m_lastOpStartIndex = -1;
@ -223,11 +230,11 @@ void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE a
{ {
angleOpCode = CalculationManager::Command::CommandDEG; angleOpCode = CalculationManager::Command::CommandDEG;
} }
if (angletype == ANGLE_RAD) else if (angletype == ANGLE_RAD)
{ {
angleOpCode = CalculationManager::Command::CommandRAD; angleOpCode = CalculationManager::Command::CommandRAD;
} }
if (angletype == ANGLE_GRAD) else // (angletype == ANGLE_GRAD)
{ {
angleOpCode = CalculationManager::Command::CommandGRAD; angleOpCode = CalculationManager::Command::CommandGRAD;
} }
@ -406,7 +413,7 @@ int CHistoryCollector::AddCommand(_In_ const std::shared_ptr<IExpressionCommand>
return nCommands - 1; return nCommands - 1;
} }
//To Update the operands in the Expression according to the current Radix // To Update the operands in the Expression according to the current Radix
void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precision) void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precision)
{ {
if (m_spTokens != nullptr) if (m_spTokens != nullptr)
@ -428,7 +435,7 @@ void CHistoryCollector::UpdateHistoryExpression(uint32_t radix, int32_t precisio
std::shared_ptr<COpndCommand> opndCommand = std::static_pointer_cast<COpndCommand>(expCommand); std::shared_ptr<COpndCommand> opndCommand = std::static_pointer_cast<COpndCommand>(expCommand);
if (opndCommand != nullptr) if (opndCommand != nullptr)
{ {
token.first = opndCommand->GetString(radix, precision, m_decimalSymbol); token.first = opndCommand->GetString(radix, precision);
IFT(m_spTokens->SetAt(i, token)); IFT(m_spTokens->SetAt(i, token));
opndCommand->SetCommands(GetOperandCommandsFromString(token.first)); opndCommand->SetCommands(GetOperandCommandsFromString(token.first));
} }
@ -444,7 +451,7 @@ void CHistoryCollector::SetDecimalSymbol(wchar_t decimalSymbol)
m_decimalSymbol = decimalSymbol; m_decimalSymbol = decimalSymbol;
} }
//Update the commands corresponding to the passed string Number // Update the commands corresponding to the passed string Number
std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr) std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFromString(wstring_view numStr)
{ {
std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>(); std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>();

View file

@ -26,39 +26,41 @@
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
// NPrecedenceOfOp namespace {
// // NPrecedenceOfOp
// returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number //
// 0 is returned. Higher the number, higher the precedence of the operator. // returns a virtual number for precedence for the operator. We expect binary operator only, otherwise the lowest number
INT NPrecedenceOfOp(int nopCode) // 0 is returned. Higher the number, higher the precedence of the operator.
{ INT NPrecedenceOfOp(int nopCode)
static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1, {
IDC_ADD,2, IDC_SUB,2, IDC_RSHF,3, IDC_LSHF,3, static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1,
IDC_MOD,3, IDC_DIV,3, IDC_MUL,3, IDC_PWR,4, IDC_ROOT, 4 }; IDC_ADD,2, IDC_SUB,2, IDC_RSHF,3, IDC_LSHF,3,
int iPrec; IDC_MOD,3, IDC_DIV,3, IDC_MUL,3, IDC_PWR,4, IDC_ROOT, 4 };
unsigned int iPrec;
iPrec = 0;
while ((iPrec < ARRAYSIZE(rgbPrec)) && (nopCode != rgbPrec[iPrec]))
{
iPrec += 2;
}
if (iPrec >= ARRAYSIZE(rgbPrec))
{
iPrec = 0; iPrec = 0;
} while ((iPrec < size(rgbPrec)) && (nopCode != rgbPrec[iPrec]))
return rgbPrec[iPrec + 1]; {
iPrec += 2;
}
if (iPrec >= size(rgbPrec))
{
iPrec = 0;
}
return rgbPrec[iPrec + 1];
}
} }
// HandleErrorCommand // HandleErrorCommand
// //
// When it is discovered by the state machine that at this point the input is not valid (eg. "1+)"), we want to proceed as though this input never // When it is discovered by the state machine that at this point the input is not valid (eg. "1+)"), we want to proceed as though this input never
// occurred and may be some feedback to user like Beep. The rest of input can then continue by just ignoring this command. // occurred and may be some feedback to user like Beep. The rest of input can then continue by just ignoring this command.
void CCalcEngine::HandleErrorCommand(WPARAM idc) void CCalcEngine::HandleErrorCommand(WPARAM idc)
{ {
if (!IsGuiSettingOpCode(idc)) if (!IsGuiSettingOpCode(idc))
{ {
// we would have saved the prev command. Need to forget this state // We would have saved the prev command. Need to forget this state
m_nTempCom = m_nLastCom; m_nTempCom = m_nLastCom;
} }
} }
@ -126,7 +128,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
} }
} }
// Toggle Record/Display mode if appropriate. // Toggle Record/Display mode if appropriate.
if (m_bRecord) if (m_bRecord)
{ {
if (IsOpInRange(wParam, IDC_AND, IDC_MMINUS) || if (IsOpInRange(wParam, IDC_AND, IDC_MMINUS) ||
@ -180,7 +182,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
// BINARY OPERATORS: // BINARY OPERATORS:
if (IsBinOpCode(wParam)) if (IsBinOpCode(wParam))
{ {
/* Change the operation if last input was operation. */ // Change the operation if last input was operation.
if (IsBinOpCode(m_nLastCom)) if (IsBinOpCode(m_nLastCom))
{ {
INT nPrev; INT nPrev;
@ -544,6 +546,11 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx) if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx)
|| ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0))) || ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0)))
{ {
if (!m_openParenCount && !nx)
{
m_pCalcDisplay->OnNoRightParenAdded();
}
HandleErrorCommand(wParam); HandleErrorCommand(wParam);
break; break;
} }
@ -567,7 +574,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
m_lastVal = 0; m_lastVal = 0;
if (IsBinOpCode(m_nLastCom)) if (IsBinOpCode(m_nLastCom))
{ {
// We want 1 + ( to start as 1 + (0. Any number you type replaces 0. But if it is 1 + 3 (, it is // We want 1 + ( to start as 1 + (0. Any number you type replaces 0. But if it is 1 + 3 (, it is
// treated as 1 + (3 // treated as 1 + (3
m_currentVal = 0; m_currentVal = 0;
} }
@ -796,7 +803,7 @@ void CCalcEngine::CheckAndAddLastBinOpToHistory(bool addToHistory)
{ {
if (m_HistoryCollector.FOpndAddedToHistory()) if (m_HistoryCollector.FOpndAddedToHistory())
{ {
// if last time opnd was added but the last command was not a binary operator, then it must have come // 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) // from commands which add the operand, like unary operator. So history at this is showing 1 + sqrt(4)
// but in reality the sqrt(4) is getting replaced by new number (may be unary op, or MR or SUM etc.) // but in reality the sqrt(4) is getting replaced by new number (may be unary op, or MR or SUM etc.)
// So erase the last operand // So erase the last operand
@ -848,7 +855,7 @@ void CCalcEngine::DisplayAnnounceBinaryOperator()
} }
// Unary operator Function Name table Element // Unary operator Function Name table Element
// since unary operators button names aren't exactly friendly for history purpose, // since unary operators button names aren't exactly friendly for history purpose,
// we have this separate table to get its localized name and for its Inv function if it exists. // we have this separate table to get its localized name and for its Inv function if it exists.
typedef struct typedef struct
{ {
@ -940,7 +947,7 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
// Try to lookup the ID in the UFNE table // Try to lookup the ID in the UFNE table
int ids = 0; int ids = 0;
int iufne = nOpCode - IDC_UNARYFIRST; int iufne = nOpCode - IDC_UNARYFIRST;
if (iufne >= 0 && iufne < ARRAYSIZE(rgUfne)) if (iufne >= 0 && (size_t)iufne < size(rgUfne))
{ {
if (fInv) if (fInv)
{ {
@ -1020,7 +1027,7 @@ wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision)
wstring numberString = GetStringForDisplay(rat, radix); wstring numberString = GetStringForDisplay(rat, radix);
if (!numberString.empty()) if (!numberString.empty())
{ {
//revert the precision to previously stored precision // Revert the precision to previously stored precision
ChangeConstants(m_radix, m_precision); ChangeConstants(m_radix, m_precision);
} }

View file

@ -104,7 +104,7 @@ void CCalcEngine::DisplayNum(void)
if (m_bRecord) if (m_bRecord)
{ {
// Display the string and return. // Display the string and return.
m_numberString = m_input.ToString(m_radix, m_fIntegerMode); m_numberString = m_input.ToString(m_radix);
} }
else else
{ {

View file

@ -70,7 +70,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
uint64_t w64Bits = result.ToUInt64_t(); uint64_t w64Bits = result.ToUInt64_t();
uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0; uint64_t lsb = ((w64Bits & 0x01) == 1) ? 1 : 0;
w64Bits >>= 1; //RShift by 1 w64Bits >>= 1; // RShift by 1
w64Bits |= (lsb << (m_dwWordBitWidth - 1)); w64Bits |= (lsb << (m_dwWordBitWidth - 1));
result = w64Bits; result = w64Bits;

View file

@ -6,15 +6,16 @@
using namespace CalcEngine; using namespace CalcEngine;
using namespace CalcEngine::RationalMath; using namespace CalcEngine::RationalMath;
using namespace std;
// To be called when either the radix or num width changes. You can use -1 in either of these values to mean // To be called when either the radix or num width changes. You can use -1 in either of these values to mean
// dont change that. // dont change that.
void CCalcEngine::SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth) void CCalcEngine::SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth)
{ {
// When in integer mode, the number is represented in 2's complement form. When a bit width is changing, we can // When in integer mode, the number is represented in 2's complement form. When a bit width is changing, we can
// change the number representation back to sign, abs num form in ratpak. Soon when display sees this, it will // change the number representation back to sign, abs num form in ratpak. Soon when display sees this, it will
// convert to 2's complement form, but this time all high bits will be propagated. Eg. -127, in byte mode is // 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 // 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. // back to 1111,1111,1000,0001 when in Word mode.
if (m_fIntegerMode) if (m_fIntegerMode)
{ {
@ -45,7 +46,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwid
// inform ratpak that a change in base or precision has occurred // inform ratpak that a change in base or precision has occurred
BaseOrPrecisionChanged(); BaseOrPrecisionChanged();
// display the correct number for the new state (ie convert displayed // display the correct number for the new state (ie convert displayed
// number to correct base) // number to correct base)
DisplayNum(); DisplayNum();
} }
@ -55,7 +56,7 @@ LONG CCalcEngine::DwWordBitWidthFromeNumWidth(NUM_WIDTH /*numwidth*/)
static constexpr int nBitMax[] = { 64, 32, 16, 8 }; static constexpr int nBitMax[] = { 64, 32, 16, 8 };
LONG wmax = nBitMax[0]; LONG wmax = nBitMax[0];
if (m_numwidth >= 0 && m_numwidth < ARRAYSIZE(nBitMax)) if (m_numwidth >= 0 && (size_t)m_numwidth < size(nBitMax))
{ {
wmax = nBitMax[m_numwidth]; wmax = nBitMax[m_numwidth];
} }
@ -68,7 +69,7 @@ uint32_t CCalcEngine::NRadixFromRadixType(RADIX_TYPE radixtype)
uint32_t radix = 10; uint32_t radix = 10;
// convert special bases into symbolic values // convert special bases into symbolic values
if (radixtype >= 0 && radixtype < ARRAYSIZE(rgnRadish)) if (radixtype >= 0 && (size_t)radixtype < size(rgnRadish))
{ {
radix = rgnRadish[radixtype]; radix = rgnRadish[radixtype];
} }
@ -142,7 +143,7 @@ void CCalcEngine::UpdateMaxIntDigits()
if (m_fIntegerMode) if (m_fIntegerMode)
{ {
m_cIntDigitsSav = static_cast<int>(m_maxDecimalValueStrings[m_numwidth].length()) - 1; m_cIntDigitsSav = static_cast<int>(m_maxDecimalValueStrings[m_numwidth].length()) - 1;
// This is the max digits you can enter a decimal in fixed width mode aka integer mode -1. The last digit // This is the max digits you can enter a decimal in fixed width mode aka integer mode -1. The last digit
// has to be checked separately // has to be checked separately
} }
else else
@ -160,10 +161,10 @@ void CCalcEngine::ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t
{ {
if (10 == radix) if (10 == radix)
{ {
ChangeConstants(radix, precision); // Base 10 precision for internal computing still needs to be 32, to 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 // take care of decimals precisely. For eg. to get the HI word of a qword, we do a rsh, which depends on getting
// 18446744073709551615 / 4294967296 = 4294967295.9999917... This is important it works this and doesn't reduce // 18446744073709551615 / 4294967296 = 4294967295.9999917... This is important it works this and doesn't reduce
// the precision to number of digits allowed to enter. In other words, precision and # of allowed digits to be // the precision to number of digits allowed to enter. In other words, precision and # of allowed digits to be
// entered are different. // entered are different.
} }
else else

View file

@ -1,26 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
class CalcException : std::exception
{
public:
CalcException(HRESULT hr)
{
m_hr = hr;
}
HRESULT GetException()
{
return m_hr;
}
private:
HRESULT m_hr;
};
void IFT(HRESULT hr)
{
if (FAILED(hr))
{
CalcException exception(hr);
throw(exception);
}
}

View file

@ -155,6 +155,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -169,6 +171,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -183,6 +187,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -197,6 +203,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -212,6 +220,8 @@
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -226,6 +236,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -240,6 +252,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -254,6 +268,8 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zm250 /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View file

@ -119,7 +119,6 @@
<ClInclude Include="Ratpack\ratpak.h"> <ClInclude Include="Ratpack\ratpak.h">
<Filter>RatPack</Filter> <Filter>RatPack</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="CalcException.h" />
<ClInclude Include="CalculatorVector.h" /> <ClInclude Include="CalculatorVector.h" />
<ClInclude Include="Header Files\CalcEngine.h"> <ClInclude Include="Header Files\CalcEngine.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
@ -136,9 +135,6 @@
<ClInclude Include="Header Files\History.h"> <ClInclude Include="Header Files\History.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Header Files\scimath.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UnitConverter.h" /> <ClInclude Include="UnitConverter.h" />
<ClInclude Include="CalculatorHistory.h" /> <ClInclude Include="CalculatorHistory.h" />
<ClInclude Include="CalculatorManager.h" /> <ClInclude Include="CalculatorManager.h" />
@ -165,4 +161,4 @@
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -23,7 +23,7 @@ unsigned int CalculatorHistory::AddToHistory(_In_ shared_ptr<CalculatorVector <p
// to be changed when pszexp is back // to be changed when pszexp is back
tokens->GetString(&generatedExpression); tokens->GetString(&generatedExpression);
// Prefixing and suffixing the special Unicode markers to ensure that the expression // Prefixing and suffixing the special Unicode markers to ensure that the expression
// in the history doesn't get broken for RTL languages // in the history doesn't get broken for RTL languages
spHistoryItem->historyItemVector.expression = L'\u202d' + generatedExpression + L'\u202c'; spHistoryItem->historyItemVector.expression = L'\u202d' + generatedExpression + L'\u202c';
spHistoryItem->historyItemVector.result = wstring(result); spHistoryItem->historyItemVector.result = wstring(result);

View file

@ -109,7 +109,6 @@ namespace CalculationManager
/// <summary> /// <summary>
/// Callback from the engine /// Callback from the engine
/// Used to set the current unmatched open parenthesis count
/// </summary> /// </summary>
/// <param name="parenthesisCount">string containing the parenthesis count</param> /// <param name="parenthesisCount">string containing the parenthesis count</param>
void CalculatorManager::SetParenDisplayText(const wstring& parenthesisCount) void CalculatorManager::SetParenDisplayText(const wstring& parenthesisCount)
@ -117,6 +116,14 @@ namespace CalculationManager
m_displayCallback->SetParenDisplayText(parenthesisCount); m_displayCallback->SetParenDisplayText(parenthesisCount);
} }
/// <summary>
/// Callback from the engine
/// </summary>
void CalculatorManager::OnNoRightParenAdded()
{
m_displayCallback->OnNoRightParenAdded();
}
/// <summary> /// <summary>
/// Reset CalculatorManager. /// Reset CalculatorManager.
/// Set the mode to the standard calculator /// Set the mode to the standard calculator
@ -293,7 +300,7 @@ namespace CalculationManager
} }
/// <summary> /// <summary>
/// Convert Command to unsigned char. /// Convert Command to unsigned char.
/// Since some Commands are higher than 255, they are saved after subtracting 255 /// Since some Commands are higher than 255, they are saved after subtracting 255
/// The smallest Command is CommandSIGN = 80, thus, subtracted value does not overlap with other values. /// The smallest Command is CommandSIGN = 80, thus, subtracted value does not overlap with other values.
/// </summary> /// </summary>
@ -428,9 +435,9 @@ namespace CalculationManager
if (*commandItr >= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber) && if (*commandItr >= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizeNumber) &&
*commandItr <= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizedNumberClearAll)) *commandItr <= MEMORY_COMMAND_TO_UNSIGNED_CHAR(MemoryCommand::MemorizedNumberClearAll))
{ {
//MemoryCommands(which have values above 255) are pushed on m_savedCommands upon casting to unsigned char. // MemoryCommands(which have values above 255) are pushed on m_savedCommands upon casting to unsigned char.
//SerializeCommands uses m_savedCommands, which is then used in DeSerializeCommands. // SerializeCommands uses m_savedCommands, which is then used in DeSerializeCommands.
//Hence, a simple cast to MemoryCommand is not sufficient. // Hence, a simple cast to MemoryCommand is not sufficient.
MemoryCommand memoryCommand = static_cast<MemoryCommand>(*commandItr + UCHAR_MAX + 1); MemoryCommand memoryCommand = static_cast<MemoryCommand>(*commandItr + UCHAR_MAX + 1);
unsigned int indexOfMemory = 0; unsigned int indexOfMemory = 0;
switch (memoryCommand) switch (memoryCommand)
@ -754,7 +761,7 @@ namespace CalculationManager
} }
void CalculatorManager::UpdateMaxIntDigits() void CalculatorManager::UpdateMaxIntDigits()
{ {
m_currentCalculatorEngine->UpdateMaxIntDigits(); m_currentCalculatorEngine->UpdateMaxIntDigits();
} }
@ -778,7 +785,7 @@ namespace CalculationManager
/// How Rational is serialized : /// How Rational is serialized :
/// Serialized Rational.P(Number) + Serialized Rational.Q(Number) /// Serialized Rational.P(Number) + Serialized Rational.Q(Number)
/// How Number is saved : /// How Number is saved :
/// [0] = Rational.P.Sign /// [0] = Rational.P.Sign
/// [1] = Rational.P.Mantissa.size /// [1] = Rational.P.Mantissa.size
/// [2] = Rational.P.Exp /// [2] = Rational.P.Exp
/// [3] = Rational.P.Mantissa[0] /// [3] = Rational.P.Mantissa[0]
@ -816,7 +823,7 @@ namespace CalculationManager
/// <summary> /// <summary>
/// Serialize Number to vector of long /// Serialize Number to vector of long
/// How Number is saved : /// How Number is saved :
/// [0] = Number.Sign /// [0] = Number.Sign
/// [1] = Number.Mantissa.size /// [1] = Number.Mantissa.size
/// [2] = Number.Exp /// [2] = Number.Exp
/// [3] = Number.Mantissa[0] /// [3] = Number.Mantissa[0]
@ -843,7 +850,7 @@ namespace CalculationManager
/// <summary> /// <summary>
/// DeserializeNumber vector and construct a Number /// DeserializeNumber vector and construct a Number
/// How Number is saved : /// How Number is saved :
/// [0] = Number.Sign /// [0] = Number.Sign
/// [1] = Number.Mantissa.size /// [1] = Number.Mantissa.size
/// [2] = Number.Exp /// [2] = Number.Exp
/// [3] = Number.Mantissa[0] /// [3] = Number.Mantissa[0]

View file

@ -27,9 +27,9 @@ namespace CalculationManager
ProgrammerModePrecision = 64 ProgrammerModePrecision = 64
}; };
// Numbering continues from the Enum Command from Command.h // Numbering continues from the Enum Command from Command.h
// with some gap to ensure there is no overlap of these ids // with some gap to ensure there is no overlap of these ids
// when static_cast<unsigned char> is performed on these ids // when static_cast<unsigned char> is performed on these ids
// they shouldn't fall in any number range greater than 80. So never // they shouldn't fall in any number range greater than 80. So never
// make the memory command ids go below 330 // make the memory command ids go below 330
enum class MemoryCommand enum class MemoryCommand
@ -42,7 +42,7 @@ namespace CalculationManager
MemorizedNumberClear = 335 MemorizedNumberClear = 335
}; };
class CalculatorManager sealed : public virtual ICalcDisplay class CalculatorManager sealed : public ICalcDisplay
{ {
private: private:
ICalcDisplay* const m_displayCallback; ICalcDisplay* const m_displayCallback;
@ -94,7 +94,8 @@ namespace CalculationManager
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override; void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(const std::wstring& parenthesisCount); void SetParenDisplayText(const std::wstring& parenthesisCount) override;
void OnNoRightParenAdded() override;
void DisplayPasteError(); void DisplayPasteError();
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;

View file

@ -10,7 +10,7 @@ namespace CalculationManager
public: public:
virtual ~IResourceProvider() { } virtual ~IResourceProvider() { }
// Should return a string from the resource table for strings used // Should return a string from the resource table for strings used
// by the calculation engine. The strings that must be defined // by the calculation engine. The strings that must be defined
// and the ids to define them with can be seen in EngineStrings.h // and the ids to define them with can be seen in EngineStrings.h
// with SIDS prefix. Additionally it must provide values for string // with SIDS prefix. Additionally it must provide values for string

View file

@ -4,7 +4,7 @@
#pragma once #pragma once
template <typename TType> template <typename TType>
class CalculatorVector class CalculatorVector
{ {
public: public:
HRESULT GetAt(_In_opt_ unsigned int index, _Out_ TType *item) HRESULT GetAt(_In_opt_ unsigned int index, _Out_ TType *item)

View file

@ -94,7 +94,7 @@ namespace CalculationManager
CommandFAC = 113, CommandFAC = 113,
CommandREC = 114, CommandREC = 114,
CommandDMS = 115, CommandDMS = 115,
CommandCUBEROOT = 116, //x ^ 1/3 CommandCUBEROOT = 116, // x ^ 1/3
CommandPOW10 = 117, // 10 ^ x CommandPOW10 = 117, // 10 ^ x
CommandPERCENT = 118, CommandPERCENT = 118,

View file

@ -75,19 +75,19 @@ void CUnaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor)
CBinaryCommand::CBinaryCommand(int command) :m_command(command) CBinaryCommand::CBinaryCommand(int command) :m_command(command)
{} {}
void CBinaryCommand::SetCommand(int command) void CBinaryCommand::SetCommand(int command)
{ {
m_command = command; m_command = command;
} }
int CBinaryCommand::GetCommand() const int CBinaryCommand::GetCommand() const
{ {
return m_command; return m_command;
} }
CalculationManager::CommandType CBinaryCommand::GetCommandType() const CalculationManager::CommandType CBinaryCommand::GetCommandType() const
{ {
return CalculationManager::CommandType::BinaryCommand; return CalculationManager::CommandType::BinaryCommand;
} }
void CBinaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor) void CBinaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor)
@ -111,8 +111,8 @@ void COpndCommand::Initialize(Rational const& rat)
} }
const shared_ptr<CalculatorVector<int>> & COpndCommand::GetCommands() const const shared_ptr<CalculatorVector<int>> & COpndCommand::GetCommands() const
{ {
return m_commands; return m_commands;
} }
void COpndCommand::SetCommands(shared_ptr<CalculatorVector<int>> const& commands) void COpndCommand::SetCommands(shared_ptr<CalculatorVector<int>> const& commands)
@ -135,7 +135,7 @@ void COpndCommand::AppendCommand(int command)
if (command == IDC_PNT) if (command == IDC_PNT)
{ {
m_fDecimal = true; m_fDecimal = true;
} }
} }
void COpndCommand::ToggleSign() void COpndCommand::ToggleSign()
@ -166,7 +166,7 @@ void COpndCommand::RemoveFromEnd()
{ {
unsigned int nCommands; unsigned int nCommands;
m_commands->GetSize(&nCommands); m_commands->GetSize(&nCommands);
if (nCommands == 1) if (nCommands == 1)
{ {
ClearAllAndAppendCommand(CalculationManager::Command::Command0); ClearAllAndAppendCommand(CalculationManager::Command::Command0);
@ -178,15 +178,15 @@ void COpndCommand::RemoveFromEnd()
if (nOpCode == IDC_PNT) if (nOpCode == IDC_PNT)
{ {
m_fDecimal = false; m_fDecimal = false;
} }
m_commands->RemoveAt(nCommands - 1); m_commands->RemoveAt(nCommands - 1);
}
} }
} }
}
bool COpndCommand::IsNegative() const bool COpndCommand::IsNegative() const
{ {
return m_fNegative; return m_fNegative;
} }
bool COpndCommand::IsSciFmt() const bool COpndCommand::IsSciFmt() const
@ -195,13 +195,13 @@ bool COpndCommand::IsSciFmt() const
} }
bool COpndCommand::IsDecimalPresent() const bool COpndCommand::IsDecimalPresent() const
{ {
return m_fDecimal; return m_fDecimal;
} }
CalculationManager::CommandType COpndCommand::GetCommandType() const CalculationManager::CommandType COpndCommand::GetCommandType() const
{ {
return CalculationManager::CommandType::OperandCommand; return CalculationManager::CommandType::OperandCommand;
} }
void COpndCommand::ClearAllAndAppendCommand(CalculationManager::Command command) void COpndCommand::ClearAllAndAppendCommand(CalculationManager::Command command)
@ -283,11 +283,11 @@ const wstring & COpndCommand::GetToken(wchar_t decimalSymbol)
m_token.clear(); m_token.clear();
m_token.append(&chZero); m_token.append(&chZero);
} }
return m_token; return m_token;
} }
wstring COpndCommand::GetString(uint32_t radix, int32_t precision, wchar_t decimalSymbol) wstring COpndCommand::GetString(uint32_t radix, int32_t precision)
{ {
wstring result{}; wstring result{};
@ -303,4 +303,3 @@ void COpndCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor)
{ {
commandVisitor.Visit(*this); commandVisitor.Visit(*this);
} }

View file

@ -10,9 +10,9 @@ class CParentheses final : public IParenthesisCommand
{ {
public: public:
CParentheses(_In_ int command); CParentheses(_In_ int command);
int GetCommand() const; int GetCommand() const override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
private: private:
int m_command; int m_command;
@ -23,11 +23,11 @@ class CUnaryCommand final : public IUnaryCommand
public: public:
CUnaryCommand(int command); CUnaryCommand(int command);
CUnaryCommand(int command1, int command2); CUnaryCommand(int command1, int command2);
const std::shared_ptr<CalculatorVector<int>> & GetCommands() const; const std::shared_ptr<CalculatorVector<int>> & GetCommands() const override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void SetCommand(int command); void SetCommand(int command) override;
void SetCommands(int command1, int command2); void SetCommands(int command1, int command2) override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
private: private:
std::shared_ptr<CalculatorVector<int>> m_command; std::shared_ptr<CalculatorVector<int>> m_command;
@ -37,10 +37,10 @@ class CBinaryCommand final : public IBinaryCommand
{ {
public: public:
CBinaryCommand(int command); CBinaryCommand(int command);
void SetCommand(int command); void SetCommand(int command) override;
int GetCommand() const; int GetCommand() const override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
private: private:
int m_command; int m_command;
@ -56,18 +56,18 @@ public:
bool fSciFmt); bool fSciFmt);
void Initialize(CalcEngine::Rational const& rat); void Initialize(CalcEngine::Rational const& rat);
const std::shared_ptr<CalculatorVector<int>> & GetCommands() const; const std::shared_ptr<CalculatorVector<int>> & GetCommands() const override;
void SetCommands(std::shared_ptr<CalculatorVector<int>> const& commands); void SetCommands(std::shared_ptr<CalculatorVector<int>> const& commands) override;
void AppendCommand(int command); void AppendCommand(int command) override;
void ToggleSign(); void ToggleSign() override;
void RemoveFromEnd(); void RemoveFromEnd() override;
bool IsNegative() const; bool IsNegative() const override;
bool IsSciFmt() const; bool IsSciFmt() const override;
bool IsDecimalPresent() const; bool IsDecimalPresent() const override;
const std::wstring & GetToken(wchar_t decimalSymbol); const std::wstring & GetToken(wchar_t decimalSymbol) override;
CalculationManager::CommandType GetCommandType() const; CalculationManager::CommandType GetCommandType() const override;
void Accept(_In_ ISerializeCommandVisitor &commandVisitor); void Accept(_In_ ISerializeCommandVisitor &commandVisitor) override;
std::wstring GetString(uint32_t radix, int32_t precision, wchar_t decimalSymbol); std::wstring GetString(uint32_t radix, int32_t precision);
private: private:
std::shared_ptr<CalculatorVector<int>> m_commands; std::shared_ptr<CalculatorVector<int>> m_commands;

View file

@ -30,7 +30,7 @@ public:
class IBinaryCommand : public IOperatorCommand class IBinaryCommand : public IOperatorCommand
{ {
public: public:
virtual void SetCommand(int command) = 0; virtual void SetCommand(int command) override = 0;
virtual int GetCommand() const = 0; virtual int GetCommand() const = 0;
}; };

View file

@ -45,7 +45,7 @@
// Key IDs: // Key IDs:
// These id's must be consecutive from IDC_FIRSTCONTROL to IDC_LASTCONTROL. // These id's must be consecutive from IDC_FIRSTCONTROL to IDC_LASTCONTROL.
// The actual values don't matter but the order and sequence are very important. // The actual values don't matter but the order and sequence are very important.
// Also, the order of the controls must match the order of the control names // Also, the order of the controls must match the order of the control names
// in the string table. // in the string table.
@ -97,7 +97,7 @@
#define IDC_FAC 113 #define IDC_FAC 113
#define IDC_REC 114 #define IDC_REC 114
#define IDC_DMS 115 #define IDC_DMS 115
#define IDC_CUBEROOT 116 //x ^ 1/3 #define IDC_CUBEROOT 116 // x ^ 1/3
#define IDC_POW10 117 // 10 ^ x #define IDC_POW10 117 // 10 ^ x
#define IDC_PERCENT 118 #define IDC_PERCENT 118
#define IDC_UNARYLAST IDC_PERCENT #define IDC_UNARYLAST IDC_PERCENT

View file

@ -85,7 +85,7 @@ private:
// if it hasn't yet been computed // if it hasn't yet been computed
bool m_bChangeOp; /* Flag for changing operation. */ bool m_bChangeOp; /* Flag for changing operation. */
bool m_bRecord; // Global mode: recording or displaying bool m_bRecord; // Global mode: recording or displaying
bool m_bSetCalcState; //Flag for setting the engine result state bool m_bSetCalcState; // Flag for setting the engine result state
CalcEngine::CalcInput m_input; // Global calc input object for decimal strings CalcEngine::CalcInput m_input; // Global calc input object for decimal strings
eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */ eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */
CalcEngine::Rational m_maxTrigonometricNum; CalcEngine::Rational m_maxTrigonometricNum;

View file

@ -6,7 +6,7 @@
#include "Rational.h" #include "Rational.h"
// Space to hold enough digits for a quadword binary number (64) plus digit separator strings for that number (20) // Space to hold enough digits for a quadword binary number (64) plus digit separator strings for that number (20)
constexpr int MAX_STRLEN = 84; constexpr int MAX_STRLEN = 84;
namespace CalcEngine namespace CalcEngine
{ {
@ -22,7 +22,7 @@ namespace CalcEngine
bool IsEmpty() { return value.empty(); } bool IsEmpty() { return value.empty(); }
bool IsNegative() { return m_isNegative; } bool IsNegative() { return m_isNegative; }
void IsNegative(bool value) { m_isNegative = value; } void IsNegative(bool isNegative) { m_isNegative = isNegative; }
std::wstring value; std::wstring value;
@ -53,7 +53,7 @@ namespace CalcEngine
bool TryBeginExponent(); bool TryBeginExponent();
void Backspace(); void Backspace();
void SetDecimalSymbol(wchar_t decSymbol); void SetDecimalSymbol(wchar_t decSymbol);
std::wstring ToString(uint32_t radix, bool isIntegerMode); std::wstring ToString(uint32_t radix);
Rational ToRational(uint32_t radix, int32_t precision); Rational ToRational(uint32_t radix, int32_t precision);
private: private:

View file

@ -128,7 +128,7 @@
#define SIDS_NFACTORIAL L"33" #define SIDS_NFACTORIAL L"33"
#define SIDS_RECIPROCAL L"34" #define SIDS_RECIPROCAL L"34"
#define SIDS_DMS L"35" #define SIDS_DMS L"35"
#define SIDS_CUBEROOT L"36" #define SIDS_CUBEROOT L"36"
#define SIDS_POWTEN L"37" #define SIDS_POWTEN L"37"
#define SIDS_PERCENT L"38" #define SIDS_PERCENT L"38"
#define SIDS_SCIENTIFIC_NOTATION L"39" #define SIDS_SCIENTIFIC_NOTATION L"39"
@ -200,7 +200,7 @@
#define SIDS_NOMEM L"105" #define SIDS_NOMEM L"105"
#define SIDS_TOOMANY L"106" #define SIDS_TOOMANY L"106"
#define SIDS_OVERFLOW L"107" #define SIDS_OVERFLOW L"107"
#define SIDS_NORESULT L"108" #define SIDS_NORESULT L"108"
#define SIDS_INSUFFICIENT_DATA L"109" #define SIDS_INSUFFICIENT_DATA L"109"
// 110 is skipped by CSTRINGSENGMAX // 110 is skipped by CSTRINGSENGMAX
#define SIDS_ERR_UNK_CH L"111" #define SIDS_ERR_UNK_CH L"111"
@ -214,7 +214,7 @@
#define SIDS_ERR_INPUT_OVERFLOW L"119" #define SIDS_ERR_INPUT_OVERFLOW L"119"
#define SIDS_ERR_OUTPUT_OVERFLOW L"120" #define SIDS_ERR_OUTPUT_OVERFLOW L"120"
__declspec(selectany) std::wstring g_sids[] = __declspec(selectany) std::wstring g_sids[] =
{ {
std::wstring(SIDS_PLUS_MINUS), std::wstring(SIDS_PLUS_MINUS),
std::wstring(SIDS_C), std::wstring(SIDS_C),
@ -252,7 +252,7 @@ __declspec(selectany) std::wstring g_sids[] =
std::wstring(SIDS_NFACTORIAL), std::wstring(SIDS_NFACTORIAL),
std::wstring(SIDS_RECIPROCAL), std::wstring(SIDS_RECIPROCAL),
std::wstring(SIDS_DMS), std::wstring(SIDS_DMS),
std::wstring(SIDS_CUBEROOT), std::wstring(SIDS_CUBEROOT),
std::wstring(SIDS_POWTEN), std::wstring(SIDS_POWTEN),
std::wstring(SIDS_PERCENT), std::wstring(SIDS_PERCENT),
std::wstring(SIDS_SCIENTIFIC_NOTATION), std::wstring(SIDS_SCIENTIFIC_NOTATION),
@ -324,7 +324,7 @@ __declspec(selectany) std::wstring g_sids[] =
std::wstring(SIDS_NOMEM), std::wstring(SIDS_NOMEM),
std::wstring(SIDS_TOOMANY), std::wstring(SIDS_TOOMANY),
std::wstring(SIDS_OVERFLOW), std::wstring(SIDS_OVERFLOW),
std::wstring(SIDS_NORESULT), std::wstring(SIDS_NORESULT),
std::wstring(SIDS_INSUFFICIENT_DATA), std::wstring(SIDS_INSUFFICIENT_DATA),
std::wstring(SIDS_ERR_UNK_CH), std::wstring(SIDS_ERR_UNK_CH),
std::wstring(SIDS_ERR_UNK_FN), std::wstring(SIDS_ERR_UNK_FN),

View file

@ -10,8 +10,8 @@
// maximum depth you can get by precedence. It is just an array's size limit. // maximum depth you can get by precedence. It is just an array's size limit.
static constexpr size_t MAXPRECDEPTH = 25; static constexpr size_t MAXPRECDEPTH = 25;
// Helper class really a internal class to CCalcEngine, to accumulate each history line of text by collecting the // Helper class really a internal class to CCalcEngine, to accumulate each history line of text by collecting the
// operands, operator, unary operator etc. Since it is a separate entity, it can be unit tested on its own but does // operands, operator, unary operator etc. Since it is a separate entity, it can be unit tested on its own but does
// rely on CCalcEngine calling it in appropriate order. // rely on CCalcEngine calling it in appropriate order.
class CHistoryCollector { class CHistoryCollector {
public: public:
@ -39,13 +39,13 @@ private:
ICalcDisplay *m_pCalcDisplay; ICalcDisplay *m_pCalcDisplay;
int m_iCurLineHistStart; // index of the beginning of the current equation 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 // 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 // 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_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_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 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 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 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; wchar_t m_decimalSymbol;
std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> m_spTokens; std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> m_spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands; std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands;

View file

@ -13,6 +13,7 @@ public:
virtual void SetIsInError(bool isInError) = 0; virtual void SetIsInError(bool isInError) = 0;
virtual void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) = 0; virtual void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) = 0;
virtual void SetParenDisplayText(const std::wstring& pszText) = 0; virtual void SetParenDisplayText(const std::wstring& pszText) = 0;
virtual void OnNoRightParenAdded() = 0;
virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer. virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer.
virtual void BinaryOperatorReceived() = 0; virtual void BinaryOperatorReceived() = 0;
virtual void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) = 0; virtual void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) = 0;

View file

@ -2,17 +2,17 @@
// Licensed under the MIT License. // Licensed under the MIT License.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Package Title ratpak // Package Title ratpak
// File basex.c // File basex.c
// Copyright (C) 1995-97 Microsoft // Copyright (C) 1995-97 Microsoft
// Date 03-14-97 // Date 03-14-97
// //
// //
// Description // Description
// //
// Contains number routines for internal base computations, these assume // Contains number routines for internal base computations, these assume
// internal base is a power of 2. // internal base is a power of 2.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h" #include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -41,7 +41,7 @@ void __inline mulnumx( PNUMBER *pa, PNUMBER b )
{ {
// If b is not one we multiply // If b is not one we multiply
if ( (*pa)->cdigit > 1 || (*pa)->mant[0] != 1 || (*pa)->exp != 0 ) if ( (*pa)->cdigit > 1 || (*pa)->mant[0] != 1 || (*pa)->exp != 0 )
{ {
// pa and b are both non-one. // pa and b are both non-one.
_mulnumx( pa, b ); _mulnumx( pa, b );
} }
@ -91,7 +91,7 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
MANTTYPE da=0; // da is the digit from the fist number. MANTTYPE da=0; // da is the digit from the fist number.
TWO_MANTTYPE cy=0; // cy is the carry resulting from the addition of TWO_MANTTYPE cy=0; // cy is the carry resulting from the addition of
// a multiplied row into the result. // a multiplied row into the result.
TWO_MANTTYPE mcy=0; // mcy is the resultant from a single TWO_MANTTYPE mcy=0; // mcy is the resultant from a single
// multiply, AND the carry of that multiply. // multiply, AND the carry of that multiply.
long icdigit=0; // Index of digit being calculated in final result. long icdigit=0; // Index of digit being calculated in final result.
@ -110,8 +110,8 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
{ {
da = *ptra++; da = *ptra++;
ptrb = b->mant; ptrb = b->mant;
// Shift ptrc, and ptrcoffset, one for each digit // Shift ptrc, and ptrcoffset, one for each digit
ptrc = ptrcoffset++; ptrc = ptrcoffset++;
for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- ) for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- )
@ -126,28 +126,28 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
c->cdigit++; c->cdigit++;
} }
} }
// If result is nonzero, or while result of carry is nonzero... // If result is nonzero, or while result of carry is nonzero...
while ( mcy || cy ) while ( mcy || cy )
{ {
// update carry from addition(s) and multiply. // update carry from addition(s) and multiply.
cy += (TWO_MANTTYPE)ptrc[icdigit]+((DWORD)mcy&((DWORD)~BASEX)); cy += (TWO_MANTTYPE)ptrc[icdigit]+((DWORD)mcy&((DWORD)~BASEX));
// update result digit from // update result digit from
ptrc[icdigit++]=(MANTTYPE)((DWORD)cy&((DWORD)~BASEX)); ptrc[icdigit++]=(MANTTYPE)((DWORD)cy&((DWORD)~BASEX));
// update carries from // update carries from
mcy >>= BASEXPWR; mcy >>= BASEXPWR;
cy >>= BASEXPWR; cy >>= BASEXPWR;
} }
ptrb++; ptrb++;
ptrc++; ptrc++;
} }
} }
// prevent different kinds of zeros, by stripping leading duplicate zeros. // prevent different kinds of zeros, by stripping leading duplicate zeros.
// digits are in order of increasing significance. // digits are in order of increasing significance.
while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 )
@ -198,7 +198,7 @@ void numpowlongx( _Inout_ PNUMBER *proot, _In_ long power )
} }
destroynum( *proot ); destroynum( *proot );
*proot=lret; *proot=lret;
} }
void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision); void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision);
@ -275,14 +275,14 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
a=*pa; a=*pa;
if ( thismax < a->cdigit ) if ( thismax < a->cdigit )
{ {
// a has more digits than precision specified, bump up digits to shoot // a has more digits than precision specified, bump up digits to shoot
// for. // for.
thismax = a->cdigit; thismax = a->cdigit;
} }
if ( thismax < b->cdigit ) if ( thismax < b->cdigit )
{ {
// b has more digits than precision specified, bump up digits to shoot // b has more digits than precision specified, bump up digits to shoot
// for. // for.
thismax = b->cdigit; thismax = b->cdigit;
} }
@ -317,7 +317,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
digit *= 2; digit *= 2;
} }
if ( lessnum( rem, tmp ) ) if ( lessnum( rem, tmp ) )
{ {
// too far, back up... // too far, back up...
destroynum( tmp ); destroynum( tmp );
digit /= 2; digit /= 2;
@ -326,7 +326,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
} }
tmp->sign *= -1; tmp->sign *= -1;
addnum( &rem, tmp, BASEX ); addnum( &rem, tmp, BASEX );
destroynum( tmp ); destroynum( tmp );
destroynum( lasttmp ); destroynum( lasttmp );
*ptrc |= digit; *ptrc |= digit;
@ -341,7 +341,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
} }
if ( !cdigits ) if ( !cdigits )
{ {
// A zero, make sure no weird exponents creep in // A zero, make sure no weird exponents creep in
c->exp = 0; c->exp = 0;
c->cdigit = 1; c->cdigit = 1;
@ -350,7 +350,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
{ {
c->cdigit = cdigits; c->cdigit = cdigits;
c->exp -= cdigits; c->exp -= cdigits;
// prevent different kinds of zeros, by stripping leading duplicate // prevent different kinds of zeros, by stripping leading duplicate
// zeros. digits are in order of increasing significance. // zeros. digits are in order of increasing significance.
while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 )
{ {

View file

@ -61,7 +61,7 @@ void* zmalloc(size_t a)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void _dupnum(_In_ PNUMBER dest, _In_ PNUMBER src) void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src)
{ {
memcpy(dest, src, (int)(sizeof(NUMBER) + ((src)->cdigit)*(sizeof(MANTTYPE)))); memcpy(dest, src, (int)(sizeof(NUMBER) + ((src)->cdigit)*(sizeof(MANTTYPE))));
} }
@ -566,7 +566,7 @@ wchar_t NormalizeCharDigit(wchar_t c, uint32_t radix)
// is in the range where this is not ambiguous. // is in the range where this is not ambiguous.
if (size_t{ radix } >= DIGITS.find(L'A') && size_t { radix } <= DIGITS.find(L'Z')) if (size_t{ radix } >= DIGITS.find(L'A') && size_t { radix } <= DIGITS.find(L'Z'))
{ {
return toupper(c); return towupper(c);
} }
return c; return c;
@ -801,7 +801,7 @@ PNUMBER longtonum( long inlong, uint32_t radix)
// RETURN: number // RETURN: number
// //
// DESCRIPTION: Returns a number representation in the // DESCRIPTION: Returns a number representation in the
// base requested of the unsigned long value passed in. Being unsigned number it has no // base requested of the unsigned long value passed in. Being unsigned number it has no
// negative number and takes the full range of unsigned number // negative number and takes the full range of unsigned number
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -817,7 +817,7 @@ PNUMBER Ulongtonum(unsigned long inlong, uint32_t radix)
pnumret->cdigit = 0; pnumret->cdigit = 0;
pnumret->exp = 0; pnumret->exp = 0;
pnumret->sign = 1; pnumret->sign = 1;
do { do {
*pmant++ = (MANTTYPE)(inlong % radix); *pmant++ = (MANTTYPE)(inlong % radix);
inlong /= radix; inlong /= radix;
@ -1057,10 +1057,6 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
length = precision; length = precision;
} }
// 2 for signs, 1 for 'e'(or leading zero), 1 for dp, 1 for null and
// 10 for maximum exponent size.
int cchNum = (precision + 16);
// If there is a chance a round has to occur, round. // If there is a chance a round has to occur, round.
// - if number is zero no rounding // - if number is zero no rounding
// - if number of digits is less than the maximum output no rounding // - if number of digits is less than the maximum output no rounding

View file

@ -46,8 +46,8 @@ void _exprat( PRAT *px, int32_t precision)
{ {
CREATETAYLOR(); CREATETAYLOR();
addnum(&(pret->pp),num_one, BASEX); addnum(&(pret->pp),num_one, BASEX);
addnum(&(pret->pq),num_one, BASEX); addnum(&(pret->pq),num_one, BASEX);
DUPRAT(thisterm,pret); DUPRAT(thisterm,pret);
n2=longtonum(0L, BASEX); n2=longtonum(0L, BASEX);
@ -81,7 +81,7 @@ void exprat( PRAT *px, uint32_t radix, int32_t precision)
ratpowlong( &pwr, intpwr, precision); ratpowlong( &pwr, intpwr, precision);
subrat(px, pint, precision); subrat(px, pint, precision);
// It just so happens to be an integral power of e. // It just so happens to be an integral power of e.
if ( rat_gt( *px, rat_negsmallest, precision) && rat_lt( *px, rat_smallest, precision) ) if ( rat_gt( *px, rat_negsmallest, precision) && rat_lt( *px, rat_smallest, precision) )
{ {
@ -131,7 +131,7 @@ void _lograt( PRAT *px, int32_t precision)
CREATETAYLOR(); CREATETAYLOR();
createrat(thisterm); createrat(thisterm);
// sub one from x // sub one from x
(*px)->pq->sign *= -1; (*px)->pq->sign *= -1;
addnum(&((*px)->pp),(*px)->pq, BASEX); addnum(&((*px)->pp),(*px)->pq, BASEX);
@ -158,14 +158,14 @@ void lograt( PRAT *px, int32_t precision)
bool fneglog; bool fneglog;
PRAT pwr = nullptr; // pwr is the large scaling factor. PRAT pwr = nullptr; // pwr is the large scaling factor.
PRAT offset = nullptr; // offset is the incremental scaling factor. PRAT offset = nullptr; // offset is the incremental scaling factor.
// Check for someone taking the log of zero or a negative number. // Check for someone taking the log of zero or a negative number.
if ( rat_le( *px, rat_zero, precision) ) if ( rat_le( *px, rat_zero, precision) )
{ {
throw( CALC_E_DOMAIN ); throw( CALC_E_DOMAIN );
} }
// Get number > 1, for scaling // Get number > 1, for scaling
fneglog = rat_lt( *px, rat_one, precision); fneglog = rat_lt( *px, rat_one, precision);
if ( fneglog ) if ( fneglog )
@ -176,12 +176,12 @@ void lograt( PRAT *px, int32_t precision)
(*px)->pp = (*px)->pq; (*px)->pp = (*px)->pq;
(*px)->pq = pnumtemp; (*px)->pq = pnumtemp;
} }
// Scale the number within BASEX factor of 1, for the large scale. // Scale the number within BASEX factor of 1, for the large scale.
// log(x*2^(BASEXPWR*k)) = BASEXPWR*k*log(2)+log(x) // log(x*2^(BASEXPWR*k)) = BASEXPWR*k*log(2)+log(x)
if ( LOGRAT2(*px) > 1 ) if ( LOGRAT2(*px) > 1 )
{ {
// Take advantage of px's base BASEX to scale quickly down to // Take advantage of px's base BASEX to scale quickly down to
// a reasonable range. // a reasonable range.
long intpwr; long intpwr;
intpwr=LOGRAT2(*px)-1; intpwr=LOGRAT2(*px)-1;
@ -206,17 +206,17 @@ void lograt( PRAT *px, int32_t precision)
} }
_lograt(px, precision); _lograt(px, precision);
// Add the large and small scaling factors, take into account // Add the large and small scaling factors, take into account
// small scaling was done in e_to_one_half chunks. // small scaling was done in e_to_one_half chunks.
divrat(&offset, rat_two, precision); divrat(&offset, rat_two, precision);
addrat(&pwr, offset, precision); addrat(&pwr, offset, precision);
// And add the resulting scaling factor to the answer. // And add the resulting scaling factor to the answer.
addrat(px, pwr, precision); addrat(px, pwr, precision);
trimit(px, precision); trimit(px, precision);
// If number started out < 1 rescale answer to negative. // If number started out < 1 rescale answer to negative.
if ( fneglog ) if ( fneglog )
{ {
@ -224,9 +224,9 @@ void lograt( PRAT *px, int32_t precision)
} }
destroyrat(offset); destroyrat(offset);
destroyrat(pwr); destroyrat(pwr);
} }
void log10rat( PRAT *px, int32_t precision) void log10rat( PRAT *px, int32_t precision)
{ {
@ -235,7 +235,7 @@ void log10rat( PRAT *px, int32_t precision)
} }
// //
// return if the given x is even number. The assumption here is its denominator is 1 and we are testing the numerator is // return if the given x is even number. The assumption here is its denominator is 1 and we are testing the numerator is
// even or not // even or not
bool IsEven(PRAT x, uint32_t radix, int32_t precision) bool IsEven(PRAT x, uint32_t radix, int32_t precision)
{ {
@ -318,7 +318,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis
// 1. Initialize result. // 1. Initialize result.
PRAT pxPow = nullptr; PRAT pxPow = nullptr;
DUPRAT(pxPow, *px); DUPRAT(pxPow, *px);
// 2. Calculate pxPow = px ^ yNumerator // 2. Calculate pxPow = px ^ yNumerator
// if yNumerator is not 1 // if yNumerator is not 1
if (!rat_equ(yNumerator, rat_one, precision)) if (!rat_equ(yNumerator, rat_one, precision))
@ -341,7 +341,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis
PRAT originalResult = nullptr; PRAT originalResult = nullptr;
DUPRAT(originalResult, pxPow); DUPRAT(originalResult, pxPow);
powratcomp(&originalResult, oneoveryDenom, radix, precision); powratcomp(&originalResult, oneoveryDenom, radix, precision);
// ################################## // ##################################
// Round the originalResult to roundedResult // Round the originalResult to roundedResult
// ################################## // ##################################
@ -375,7 +375,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis
else else
{ {
DUPRAT(*px, originalResult); DUPRAT(*px, originalResult);
} }
destroyrat(oneoveryDenom); destroyrat(oneoveryDenom);
destroyrat(originalResult); destroyrat(originalResult);
@ -429,7 +429,7 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
sign = 1; sign = 1;
} }
} }
else else
{ {
PRAT pxint= nullptr; PRAT pxint= nullptr;
DUPRAT(pxint,*px); DUPRAT(pxint,*px);
@ -491,7 +491,7 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
PRAT pNumerator = nullptr; PRAT pNumerator = nullptr;
PRAT pDenominator = nullptr; PRAT pDenominator = nullptr;
bool fBadExponent = false; bool fBadExponent = false;
// Get the numbers in arbitrary precision rational number format // Get the numbers in arbitrary precision rational number format
DUPRAT(pNumerator, rat_zero); // pNumerator->pq is 1 one DUPRAT(pNumerator, rat_zero); // pNumerator->pq is 1 one
DUPRAT(pDenominator, rat_zero); // pDenominator->pq is 1 one DUPRAT(pDenominator, rat_zero); // pDenominator->pq is 1 one
@ -516,7 +516,7 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
} }
destroyrat(pNumerator); destroyrat(pNumerator);
destroyrat(pDenominator); destroyrat(pDenominator);
if (fBadExponent) if (fBadExponent)
{ {
throw( CALC_E_DOMAIN ); throw( CALC_E_DOMAIN );

View file

@ -73,17 +73,17 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
PRAT ratprec = nullptr; PRAT ratprec = nullptr;
PRAT ratRadix = nullptr; PRAT ratRadix = nullptr;
long oldprec; long oldprec;
// Set up constants and initial conditions // Set up constants and initial conditions
oldprec = precision; oldprec = precision;
ratprec = longtorat( oldprec ); ratprec = longtorat( oldprec );
// Find the best 'A' for convergence to the required precision. // Find the best 'A' for convergence to the required precision.
a=longtorat( radix ); a=longtorat( radix );
lograt(&a, precision); lograt(&a, precision);
mulrat(&a, ratprec, precision); mulrat(&a, ratprec, precision);
// Really is -ln(n)+1, but -ln(n) will be < 1 // Really is -ln(n)+1, but -ln(n) will be < 1
// if we scale n between 0.5 and 1.5 // if we scale n between 0.5 and 1.5
addrat(&a, rat_two, precision); addrat(&a, rat_two, precision);
DUPRAT(tmp,a); DUPRAT(tmp,a);
@ -91,9 +91,9 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
mulrat(&tmp, *pn, precision); mulrat(&tmp, *pn, precision);
addrat(&a, tmp, precision); addrat(&a, tmp, precision);
addrat(&a, rat_one, precision); addrat(&a, rat_one, precision);
// Calculate the necessary bump in precision and up the precision. // Calculate the necessary bump in precision and up the precision.
// The following code is equivalent to // The following code is equivalent to
// precision += ln(exp(a)*pow(a,n+1.5))-ln(radix)); // precision += ln(exp(a)*pow(a,n+1.5))-ln(radix));
DUPRAT(tmp,*pn); DUPRAT(tmp,*pn);
one_pt_five=longtorat( 3L ); one_pt_five=longtorat( 3L );
@ -110,7 +110,7 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
lograt( &tmp, precision); lograt( &tmp, precision);
subrat( &term, tmp, precision); subrat( &term, tmp, precision);
precision += rattolong( term, radix, precision); precision += rattolong( term, radix, precision);
// Set up initial terms for series, refer to series in above comment block. // Set up initial terms for series, refer to series in above comment block.
DUPRAT(factorial,rat_one); // Start factorial out with one DUPRAT(factorial,rat_one); // Start factorial out with one
count = longtonum( 0L, BASEX ); count = longtonum( 0L, BASEX );
@ -120,7 +120,7 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
// a2=a^2 // a2=a^2
DUPRAT(a2,a); DUPRAT(a2,a);
mulrat(&a2, a, precision); mulrat(&a2, a, precision);
// sum=(1/n)-(a/(n+1)) // sum=(1/n)-(a/(n+1))
DUPRAT(sum,rat_one); DUPRAT(sum,rat_one);
divrat(&sum, *pn, precision); divrat(&sum, *pn, precision);
@ -136,14 +136,14 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
divrat(&err, ratRadix, precision); divrat(&err, ratRadix, precision);
// Just get something not tiny in term // Just get something not tiny in term
DUPRAT(term, rat_two ); DUPRAT(term, rat_two );
// Loop until precision is reached, or asked to halt. // Loop until precision is reached, or asked to halt.
while ( !zerrat( term ) && rat_gt( term, err, precision) ) while ( !zerrat( term ) && rat_gt( term, err, precision) )
{ {
addrat(pn, rat_two, precision); addrat(pn, rat_two, precision);
// WARNING: mixing numbers and rationals here. // WARNING: mixing numbers and rationals here.
// for speed and efficiency. // for speed and efficiency.
INC(count); INC(count);
mulnumx(&(factorial->pp),count); mulnumx(&(factorial->pp),count);
@ -166,15 +166,15 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
DUPRAT(term,rat_one); DUPRAT(term,rat_one);
divrat( &term, *pn, precision); divrat( &term, *pn, precision);
subrat( &term, tmp, precision); subrat( &term, tmp, precision);
divrat (&term, factorial, precision); divrat (&term, factorial, precision);
addrat( &sum, term, precision); addrat( &sum, term, precision);
ABSRAT(term); ABSRAT(term);
} }
// Multiply by factor. // Multiply by factor.
mulrat( &sum, mpy, precision); mulrat( &sum, mpy, precision);
// And cleanup // And cleanup
precision = oldprec; precision = oldprec;
destroyrat(ratprec); destroyrat(ratprec);
@ -199,13 +199,13 @@ void factrat( PRAT *px, uint32_t radix, int32_t precision)
PRAT fact = nullptr; PRAT fact = nullptr;
PRAT frac = nullptr; PRAT frac = nullptr;
PRAT neg_rat_one = nullptr; PRAT neg_rat_one = nullptr;
if ( rat_gt( *px, rat_max_fact, precision) || rat_lt( *px, rat_min_fact, precision) ) if ( rat_gt( *px, rat_max_fact, precision) || rat_lt( *px, rat_min_fact, precision) )
{ {
// Don't attempt factorial of anything too large or small. // Don't attempt factorial of anything too large or small.
throw CALC_E_OVERFLOW; throw CALC_E_OVERFLOW;
} }
DUPRAT(fact,rat_one); DUPRAT(fact,rat_one);
DUPRAT(neg_rat_one,rat_one); DUPRAT(neg_rat_one,rat_one);
@ -226,7 +226,7 @@ void factrat( PRAT *px, uint32_t radix, int32_t precision)
mulrat( &fact, *px, precision); mulrat( &fact, *px, precision);
subrat( px, rat_one, precision); subrat( px, rat_one, precision);
} }
// Added to make numbers 'close enough' to integers use integer factorial. // Added to make numbers 'close enough' to integers use integer factorial.
if ( LOGRATRADIX(*px) <= -precision) if ( LOGRATRADIX(*px) <= -precision)
{ {

View file

@ -69,13 +69,13 @@ void _asinrat( PRAT *px, int32_t precision)
{ {
CREATETAYLOR(); CREATETAYLOR();
DUPRAT(pret,*px); DUPRAT(pret,*px);
DUPRAT(thisterm,*px); DUPRAT(thisterm,*px);
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
do do
{ {
NEXTTERM(xx,MULNUM(n2) MULNUM(n2) NEXTTERM(xx,MULNUM(n2) MULNUM(n2)
INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision);
} }
while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); while ( !SMALL_ENOUGH_RAT( thisterm, precision) );
@ -100,7 +100,7 @@ void asinrat( PRAT *px, uint32_t radix, int32_t precision)
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;
// Avoid the really bad part of the asin curve near +/-1. // Avoid the really bad part of the asin curve near +/-1.
DUPRAT(phack,*px); DUPRAT(phack,*px);
subrat(&phack, rat_one, precision); subrat(&phack, rat_one, precision);
@ -185,15 +185,15 @@ void _acosrat( PRAT *px, int32_t precision)
{ {
CREATETAYLOR(); CREATETAYLOR();
createrat(thisterm); createrat(thisterm);
thisterm->pp=longtonum( 1L, BASEX ); thisterm->pp=longtonum( 1L, BASEX );
thisterm->pq=longtonum( 1L, BASEX ); thisterm->pq=longtonum( 1L, BASEX );
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
do do
{ {
NEXTTERM(xx,MULNUM(n2) MULNUM(n2) NEXTTERM(xx,MULNUM(n2) MULNUM(n2)
INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision);
} }
while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); while ( !SMALL_ENOUGH_RAT( thisterm, precision) );
@ -210,7 +210,7 @@ void acosrat( PRAT *px, uint32_t radix, int32_t precision)
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;
if ( rat_equ( *px, rat_one, precision) ) if ( rat_equ( *px, rat_one, precision) )
{ {
if ( sgn == -1 ) if ( sgn == -1 )
@ -274,7 +274,7 @@ void _atanrat( PRAT *px, int32_t precision)
{ {
CREATETAYLOR(); CREATETAYLOR();
DUPRAT(pret,*px); DUPRAT(pret,*px);
DUPRAT(thisterm,*px); DUPRAT(thisterm,*px);
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
@ -298,7 +298,7 @@ void atanrat( PRAT *px, uint32_t radix, int32_t precision)
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->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) )
@ -314,7 +314,7 @@ void atanrat( PRAT *px, uint32_t radix, int32_t precision)
subrat(px, tmpx, precision); subrat(px, tmpx, precision);
destroyrat( tmpx ); destroyrat( tmpx );
} }
else else
{ {
(*px)->pp->sign = sgn; (*px)->pp->sign = sgn;
DUPRAT(tmpx,*px); DUPRAT(tmpx,*px);

View file

@ -60,7 +60,7 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision)
if ( rat_gt( *px, pt_eight_five, precision) || rat_lt( *px, neg_pt_eight_five, precision) ) if ( rat_gt( *px, pt_eight_five, precision) || rat_lt( *px, neg_pt_eight_five, precision) )
{ {
PRAT ptmp = nullptr; PRAT ptmp = nullptr;
DUPRAT(ptmp,(*px)); DUPRAT(ptmp,(*px));
mulrat(&ptmp, *px, precision); mulrat(&ptmp, *px, precision);
addrat(&ptmp, rat_one, precision); addrat(&ptmp, rat_one, precision);
rootrat(&ptmp, rat_two, radix, precision); rootrat(&ptmp, rat_two, radix, precision);
@ -73,14 +73,14 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision)
CREATETAYLOR(); CREATETAYLOR();
xx->pp->sign *= -1; xx->pp->sign *= -1;
DUPRAT(pret,(*px)); DUPRAT(pret,(*px));
DUPRAT(thisterm,(*px)); DUPRAT(thisterm,(*px));
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
do do
{ {
NEXTTERM(xx,MULNUM(n2) MULNUM(n2) NEXTTERM(xx,MULNUM(n2) MULNUM(n2)
INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision);
} }
while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); while ( !SMALL_ENOUGH_RAT( thisterm, precision) );
@ -99,7 +99,7 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision)
// hyperbolic cose of // hyperbolic cose of
// RETURN: acosh of x in PRAT form. // RETURN: acosh of x in PRAT form.
// //
// EXPLANATION: This uses // EXPLANATION: This uses
// //
// acosh(x)=ln(x+sqrt(x^2-1)) // acosh(x)=ln(x+sqrt(x^2-1))
// //
@ -117,7 +117,7 @@ void acoshrat( PRAT *px, uint32_t radix, int32_t precision)
else else
{ {
PRAT ptmp = nullptr; PRAT ptmp = nullptr;
DUPRAT(ptmp,(*px)); DUPRAT(ptmp,(*px));
mulrat(&ptmp, *px, precision); mulrat(&ptmp, *px, precision);
subrat(&ptmp, rat_one, precision); subrat(&ptmp, rat_one, precision);
rootrat(&ptmp,rat_two, radix, precision); rootrat(&ptmp,rat_two, radix, precision);
@ -148,7 +148,7 @@ void atanhrat( PRAT *px, int32_t precision)
{ {
PRAT ptmp = nullptr; PRAT ptmp = nullptr;
DUPRAT(ptmp,(*px)); DUPRAT(ptmp,(*px));
subrat(&ptmp, rat_one, precision); subrat(&ptmp, rat_one, precision);
addrat(px, rat_one, precision); addrat(px, rat_one, precision);
divrat(px, ptmp, precision); divrat(px, ptmp, precision);

View file

@ -49,7 +49,7 @@ void rshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
intrat(pa, radix, precision); intrat(pa, radix, precision);
if ( !zernum( (*pa)->pp ) ) if ( !zernum( (*pa)->pp ) )
{ {
// If input is zero we're done. // If input is zero we're done.
if ( rat_lt( b, rat_min_exp, precision) ) if ( rat_lt( b, rat_min_exp, precision) )
{ {
@ -155,11 +155,11 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
pchc = c->mant; pchc = c->mant;
for ( ;cdigits > 0; cdigits--, mexp++ ) for ( ;cdigits > 0; cdigits--, mexp++ )
{ {
da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp >
(c->cdigit - a->cdigit) ) ) ? (c->cdigit - a->cdigit) ) ) ?
*pcha++ : 0 ); *pcha++ : 0 );
db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp >
(c->cdigit - b->cdigit) ) ) ? (c->cdigit - b->cdigit) ) ) ?
*pchb++ : 0 ); *pchb++ : 0 );
switch ( func ) switch ( func )
{ {
@ -205,15 +205,14 @@ void modrat( PRAT *pa, PRAT b )
throw CALC_E_INDEFINITE; throw CALC_E_INDEFINITE;
} }
DUPRAT(tmp,b); DUPRAT(tmp,b);
mulnumx( &((*pa)->pp), tmp->pq ); mulnumx( &((*pa)->pp), tmp->pq );
mulnumx( &(tmp->pp), (*pa)->pq ); mulnumx( &(tmp->pp), (*pa)->pq );
remnum( &((*pa)->pp), tmp->pp, BASEX ); remnum( &((*pa)->pp), tmp->pp, BASEX );
mulnumx( &((*pa)->pq), tmp->pq ); mulnumx( &((*pa)->pq), tmp->pq );
//Get *pa back in the integer over integer form. // Get *pa back in the integer over integer form.
RENORMALIZE(*pa); RENORMALIZE(*pa);
destroyrat( tmp ); destroyrat( tmp );
} }

View file

@ -2,20 +2,20 @@
// Licensed under the MIT License. // Licensed under the MIT License.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Package Title ratpak // Package Title ratpak
// File num.c // File num.c
// Copyright (C) 1995-97 Microsoft // Copyright (C) 1995-97 Microsoft
// Date 01-16-95 // Date 01-16-95
// //
// //
// Description // Description
// //
// Contains number routines for add, mul, div, rem and other support // Contains number routines for add, mul, div, rem and other support
// and longs. // and longs.
// //
// Special Information // Special Information
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h" #include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -76,8 +76,8 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
long fcomplb = 0; // fcomplb is a flag to signal b is negative. long fcomplb = 0; // fcomplb is a flag to signal b is negative.
a=*pa; a=*pa;
// Calculate the overlap of the numbers after alignment, this includes // Calculate the overlap of the numbers after alignment, this includes
// necessary padding 0's // necessary padding 0's
cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) - cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) -
@ -90,7 +90,7 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
pcha = a->mant; pcha = a->mant;
pchb = b->mant; pchb = b->mant;
pchc = c->mant; pchc = c->mant;
// Figure out the sign of the numbers // Figure out the sign of the numbers
if ( a->sign != b->sign ) if ( a->sign != b->sign )
{ {
@ -98,21 +98,21 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
fcompla = ( a->sign == -1 ); fcompla = ( a->sign == -1 );
fcomplb = ( b->sign == -1 ); fcomplb = ( b->sign == -1 );
} }
// Loop over all the digits, real and 0 padded. Here we know a and b are // Loop over all the digits, real and 0 padded. Here we know a and b are
// aligned // aligned
for ( ;cdigits > 0; cdigits--, mexp++ ) for ( ;cdigits > 0; cdigits--, mexp++ )
{ {
// Get digit from a, taking padding into account. // Get digit from a, taking padding into account.
da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp >
(c->cdigit - a->cdigit) ) ) ? (c->cdigit - a->cdigit) ) ) ?
*pcha++ : 0 ); *pcha++ : 0 );
// Get digit from b, taking padding into account. // Get digit from b, taking padding into account.
db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp >
(c->cdigit - b->cdigit) ) ) ? (c->cdigit - b->cdigit) ) ) ?
*pchb++ : 0 ); *pchb++ : 0 );
// Handle complementing for a and b digit. Might be a better way, but // Handle complementing for a and b digit. Might be a better way, but
// haven't found it yet. // haven't found it yet.
if ( fcompla ) if ( fcompla )
@ -123,20 +123,20 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
{ {
db = (MANTTYPE)(radix) - 1 - db; db = (MANTTYPE)(radix) - 1 - db;
} }
// Update carry as necessary // Update carry as necessary
cy = da + db + cy; cy = da + db + cy;
*pchc++ = (MANTTYPE)(cy % (MANTTYPE)radix); *pchc++ = (MANTTYPE)(cy % (MANTTYPE)radix);
cy /= (MANTTYPE)radix; cy /= (MANTTYPE)radix;
} }
// Handle carry from last sum as extra digit // Handle carry from last sum as extra digit
if ( cy && !(fcompla || fcomplb) ) if ( cy && !(fcompla || fcomplb) )
{ {
*pchc++ = cy; *pchc++ = cy;
c->cdigit++; c->cdigit++;
} }
// Compute sign of result // Compute sign of result
if ( !(fcompla || fcomplb) ) if ( !(fcompla || fcomplb) )
{ {
@ -150,14 +150,14 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
} }
else else
{ {
// In this particular case an overflow or underflow has occurred // In this particular case an overflow or underflow has occurred
// and all the digits need to be complemented, at one time an // and all the digits need to be complemented, at one time an
// attempt to handle this above was made, it turned out to be much // attempt to handle this above was made, it turned out to be much
// slower on average. // slower on average.
c->sign = -1; c->sign = -1;
cy = 1; cy = 1;
for ( ( cdigits = c->cdigit ), (pchc = c->mant); for ( ( cdigits = c->cdigit ), (pchc = c->mant);
cdigits > 0; cdigits > 0;
cdigits-- ) cdigits-- )
{ {
cy = (MANTTYPE)radix - (MANTTYPE)1 - *pchc + cy; cy = (MANTTYPE)radix - (MANTTYPE)1 - *pchc + cy;
@ -166,7 +166,7 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
} }
} }
} }
// Remove leading zeros, remember digits are in order of // Remove leading zeros, remember digits are in order of
// increasing significance. i.e. 100 would be 0,0,1 // increasing significance. i.e. 100 would be 0,0,1
while ( c->cdigit > 1 && *(--pchc) == 0 ) while ( c->cdigit > 1 && *(--pchc) == 0 )
@ -231,7 +231,7 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
MANTTYPE da = 0; // da is the digit from the fist number. MANTTYPE da = 0; // da is the digit from the fist number.
TWO_MANTTYPE cy = 0; // cy is the carry resulting from the addition of TWO_MANTTYPE cy = 0; // cy is the carry resulting from the addition of
// a multiplied row into the result. // a multiplied row into the result.
TWO_MANTTYPE mcy = 0; // mcy is the resultant from a single TWO_MANTTYPE mcy = 0; // mcy is the resultant from a single
// multiply, AND the carry of that multiply. // multiply, AND the carry of that multiply.
long icdigit = 0; // Index of digit being calculated in final result. long icdigit = 0; // Index of digit being calculated in final result.
@ -249,8 +249,8 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
{ {
da = *pcha++; da = *pcha++;
pchb = b->mant; pchb = b->mant;
// Shift pchc, and pchcoffset, one for each digit // Shift pchc, and pchcoffset, one for each digit
pchc = pchcoffset++; pchc = pchcoffset++;
for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- ) for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- )
@ -268,23 +268,23 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// If result is nonzero, or while result of carry is nonzero... // If result is nonzero, or while result of carry is nonzero...
while ( mcy || cy ) while ( mcy || cy )
{ {
// update carry from addition(s) and multiply. // update carry from addition(s) and multiply.
cy += (TWO_MANTTYPE)pchc[icdigit]+(mcy%(TWO_MANTTYPE)radix); cy += (TWO_MANTTYPE)pchc[icdigit]+(mcy%(TWO_MANTTYPE)radix);
// update result digit from // update result digit from
pchc[icdigit++]=(MANTTYPE)(cy%(TWO_MANTTYPE)radix); pchc[icdigit++]=(MANTTYPE)(cy%(TWO_MANTTYPE)radix);
// update carries from // update carries from
mcy /= (TWO_MANTTYPE)radix; mcy /= (TWO_MANTTYPE)radix;
cy /= (TWO_MANTTYPE)radix; cy /= (TWO_MANTTYPE)radix;
} }
pchb++; pchb++;
pchc++; pchc++;
} }
} }
// prevent different kinds of zeros, by stripping leading duplicate zeros. // prevent different kinds of zeros, by stripping leading duplicate zeros.
// digits are in order of increasing significance. // digits are in order of increasing significance.
while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 )
@ -317,7 +317,7 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
{ {
PNUMBER tmp = nullptr; // tmp is the working remainder. PNUMBER tmp = nullptr; // tmp is the working remainder.
PNUMBER lasttmp = nullptr; // lasttmp is the last remainder which worked. PNUMBER lasttmp = nullptr; // lasttmp is the last remainder which worked.
// Once *pa is less than b, *pa is the remainder. // Once *pa is less than b, *pa is the remainder.
while ( !lessnum( *pa, b ) ) while ( !lessnum( *pa, b ) )
{ {
@ -336,20 +336,20 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
destroynum( lasttmp ); destroynum( lasttmp );
lasttmp=longtonum( 0, radix); lasttmp=longtonum( 0, radix);
while ( lessnum( tmp, *pa ) ) while ( lessnum( tmp, *pa ) )
{ {
DUPNUM( lasttmp, tmp ); DUPNUM( lasttmp, tmp );
addnum( &tmp, tmp, radix); addnum( &tmp, tmp, radix);
} }
if ( lessnum( *pa, tmp ) ) if ( lessnum( *pa, tmp ) )
{ {
// too far, back up... // too far, back up...
destroynum( tmp ); destroynum( tmp );
tmp=lasttmp; tmp=lasttmp;
lasttmp= nullptr; lasttmp= nullptr;
} }
// Subtract the working remainder from the remainder holder. // Subtract the working remainder from the remainder holder.
tmp->sign = -1*(*pa)->sign; tmp->sign = -1*(*pa)->sign;
addnum( pa, tmp, radix); addnum( pa, tmp, radix);
@ -357,7 +357,7 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
destroynum( tmp ); destroynum( tmp );
destroynum( lasttmp ); destroynum( lasttmp );
} }
} }
@ -381,7 +381,7 @@ void __inline divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision)
{ {
if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 ) if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 )
{ {
// b is not one // b is not one
_divnum( pa, b, radix, precision); _divnum( pa, b, radix, precision);
} }
@ -418,7 +418,7 @@ void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision)
tmp->sign = a->sign; tmp->sign = a->sign;
rem->exp = b->cdigit + b->exp - rem->cdigit; rem->exp = b->cdigit + b->exp - rem->cdigit;
// Build a table of multiplications of the divisor, this is quicker for // Build a table of multiplications of the divisor, this is quicker for
// more than radix 'digits' // more than radix 'digits'
list<PNUMBER> numberList{ longtonum(0L, radix) }; list<PNUMBER> numberList{ longtonum(0L, radix) };
for (unsigned long i = 1; i < radix; i++) for (unsigned long i = 1; i < radix; i++)
@ -535,21 +535,21 @@ bool equnum( PNUMBER a, PNUMBER b )
pb += b->cdigit - 1; pb += b->cdigit - 1;
cdigits = max( a->cdigit, b->cdigit ); cdigits = max( a->cdigit, b->cdigit );
ccdigits = cdigits; ccdigits = cdigits;
// Loop over all digits until we run out of digits or there is a // Loop over all digits until we run out of digits or there is a
// difference in the digits. // difference in the digits.
for ( ;cdigits > 0; cdigits-- ) for ( ;cdigits > 0; cdigits-- )
{ {
da = ( (cdigits > (ccdigits - a->cdigit) ) ? da = ( (cdigits > (ccdigits - a->cdigit) ) ?
*pa-- : 0 ); *pa-- : 0 );
db = ( (cdigits > (ccdigits - b->cdigit) ) ? db = ( (cdigits > (ccdigits - b->cdigit) ) ?
*pb-- : 0 ); *pb-- : 0 );
if ( da != db ) if ( da != db )
{ {
return false; return false;
} }
} }
// In this case, they are equal. // In this case, they are equal.
return true; return true;
} }
@ -604,9 +604,9 @@ bool lessnum( PNUMBER a, PNUMBER b )
ccdigits = cdigits; ccdigits = cdigits;
for ( ;cdigits > 0; cdigits-- ) for ( ;cdigits > 0; cdigits-- )
{ {
da = ( (cdigits > (ccdigits - a->cdigit) ) ? da = ( (cdigits > (ccdigits - a->cdigit) ) ?
*pa-- : 0 ); *pa-- : 0 );
db = ( (cdigits > (ccdigits - b->cdigit) ) ? db = ( (cdigits > (ccdigits - b->cdigit) ) ?
*pb-- : 0 ); *pb-- : 0 );
diff = da-db; diff = da-db;
if ( diff ) if ( diff )
@ -639,8 +639,8 @@ bool zernum( PNUMBER a )
MANTTYPE *pcha; MANTTYPE *pcha;
length = a->cdigit; length = a->cdigit;
pcha = a->mant; pcha = a->mant;
// loop over all the digits until you find a nonzero or until you run // loop over all the digits until you find a nonzero or until you run
// out of digits // out of digits
while ( length-- > 0 ) while ( length-- > 0 )
{ {

View file

@ -38,7 +38,7 @@ using namespace std;
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void gcdrat( PRAT *pa, uint32_t radix, int32_t precision) void gcdrat( PRAT *pa, int32_t precision)
{ {
PNUMBER pgcd= nullptr; PNUMBER pgcd= nullptr;
@ -56,7 +56,7 @@ void gcdrat( PRAT *pa, uint32_t radix, int32_t precision)
destroynum( pgcd ); destroynum( pgcd );
*pa=a; *pa=a;
RENORMALIZE(*pa); RENORMALIZE(*pa);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -82,7 +82,7 @@ void fracrat( PRAT *pa , uint32_t radix, int32_t precision)
remnum( &((*pa)->pp), (*pa)->pq, BASEX ); remnum( &((*pa)->pp), (*pa)->pq, BASEX );
//Get *pa back in the integer over integer form. // Get *pa back in the integer over integer form.
RENORMALIZE(*pa); RENORMALIZE(*pa);
} }
@ -100,7 +100,7 @@ void fracrat( PRAT *pa , uint32_t radix, int32_t precision)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void mulrat( PRAT *pa, PRAT b, int32_t precision) void mulrat( PRAT *pa, PRAT b, int32_t precision)
{ {
// Only do the multiply if it isn't zero. // Only do the multiply if it isn't zero.
if ( !zernum( (*pa)->pp ) ) if ( !zernum( (*pa)->pp ) )
@ -170,7 +170,7 @@ void divrat( PRAT *pa, PRAT b, int32_t precision)
#ifdef DIVGCD #ifdef DIVGCD
gcdrat( pa ); gcdrat( pa );
#endif #endif
} }
@ -215,13 +215,13 @@ void addrat( PRAT *pa, PRAT b, int32_t precision)
if ( equnum( (*pa)->pq, b->pq ) ) if ( equnum( (*pa)->pq, b->pq ) )
{ {
// Very special case, q's match., // Very special case, q's match.,
// make sure signs are involved in the calculation // make sure signs are involved in the calculation
// we have to do this since the optimization here is only // we have to do this since the optimization here is only
// working with the top half of the rationals. // working with the top half of the rationals.
(*pa)->pp->sign *= (*pa)->pq->sign; (*pa)->pp->sign *= (*pa)->pq->sign;
(*pa)->pq->sign = 1; (*pa)->pq->sign = 1;
b->pp->sign *= b->pq->sign; b->pp->sign *= b->pq->sign;
b->pq->sign = 1; b->pq->sign = 1;
addnum( &((*pa)->pp), b->pp, BASEX ); addnum( &((*pa)->pp), b->pp, BASEX );
} }
@ -236,15 +236,15 @@ void addrat( PRAT *pa, PRAT b, int32_t precision)
destroynum( (*pa)->pq ); destroynum( (*pa)->pq );
(*pa)->pq = bot; (*pa)->pq = bot;
trimit(pa, precision); trimit(pa, precision);
// Get rid of negative zeros here. // Get rid of negative zeros here.
(*pa)->pp->sign *= (*pa)->pq->sign; (*pa)->pp->sign *= (*pa)->pq->sign;
(*pa)->pq->sign = 1; (*pa)->pq->sign = 1;
} }
#ifdef ADDGCD #ifdef ADDGCD
gcdrat( pa ); gcdrat( pa );
#endif #endif
} }
@ -264,7 +264,7 @@ void addrat( PRAT *pa, PRAT b, int32_t precision)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void rootrat( PRAT *py, PRAT n, uint32_t radix, int32_t precision) void rootrat( PRAT *py, PRAT n, uint32_t radix, int32_t precision)
{ {
// Initialize 1/n // Initialize 1/n
PRAT oneovern= nullptr; PRAT oneovern= nullptr;
DUPRAT(oneovern,rat_one); DUPRAT(oneovern,rat_one);

View file

@ -1,480 +1,482 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// Autogenerated by _dumprawrat in support.c #pragma once
NUMBER init_num_one= {
// Autogenerated by _dumprawrat in support.cpp
inline const NUMBER init_num_one= {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_two= { inline const NUMBER init_num_two= {
1, 1,
1, 1,
0, 0,
{ 2,} { 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_five= { inline const NUMBER init_num_five= {
1, 1,
1, 1,
0, 0,
{ 5,} { 5,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_six= { inline const NUMBER init_num_six= {
1, 1,
1, 1,
0, 0,
{ 6,} { 6,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_num_ten= { inline const NUMBER init_num_ten= {
1, 1,
1, 1,
0, 0,
{ 10,} { 10,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_smallest = { inline const NUMBER init_p_rat_smallest = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_smallest = { inline const NUMBER init_q_rat_smallest = {
1, 1,
4, 4,
0, 0,
{ 0, 190439170, 901055854, 10097,} { 0, 190439170, 901055854, 10097,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_negsmallest = { inline const NUMBER init_p_rat_negsmallest = {
-1, -1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_negsmallest = { inline const NUMBER init_q_rat_negsmallest = {
1, 1,
4, 4,
0, 0,
{ 0, 190439170, 901055854, 10097,} { 0, 190439170, 901055854, 10097,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_pt_eight_five = { inline const NUMBER init_p_pt_eight_five = {
1, 1,
1, 1,
0, 0,
{ 85,} { 85,}
}; };
NUMBER init_q_pt_eight_five = { inline const NUMBER init_q_pt_eight_five = {
1, 1,
1, 1,
0, 0,
{ 100,} { 100,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_six = { inline const NUMBER init_p_rat_six = {
1, 1,
1, 1,
0, 0,
{ 6,} { 6,}
}; };
NUMBER init_q_rat_six = { inline const NUMBER init_q_rat_six = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_two = { inline const NUMBER init_p_rat_two = {
1, 1,
1, 1,
0, 0,
{ 2,} { 2,}
}; };
NUMBER init_q_rat_two = { inline const NUMBER init_q_rat_two = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_zero = { inline const NUMBER init_p_rat_zero = {
1, 1,
1, 1,
0, 0,
{ 0,} { 0,}
}; };
NUMBER init_q_rat_zero = { inline const NUMBER init_q_rat_zero = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_one = { inline const NUMBER init_p_rat_one = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_one = { inline const NUMBER init_q_rat_one = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_neg_one = { inline const NUMBER init_p_rat_neg_one = {
-1, -1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_neg_one = { inline const NUMBER init_q_rat_neg_one = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_half = { inline const NUMBER init_p_rat_half = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
NUMBER init_q_rat_half = { inline const NUMBER init_q_rat_half = {
1, 1,
1, 1,
0, 0,
{ 2,} { 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_ten = { inline const NUMBER init_p_rat_ten = {
1, 1,
1, 1,
0, 0,
{ 10,} { 10,}
}; };
NUMBER init_q_rat_ten = { inline const NUMBER init_q_rat_ten = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_pi = { inline const NUMBER init_p_pi = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
NUMBER init_q_pi = { inline const NUMBER init_q_pi = {
1, 1,
6, 6,
0, 0,
{ 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,} { 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_two_pi = { inline const NUMBER init_p_two_pi = {
1, 1,
6, 6,
0, 0,
{ 251055792, 567796700, 1773504224, 1198217877, 428852897, 17,} { 251055792, 567796700, 1773504224, 1198217877, 428852897, 17,}
}; };
NUMBER init_q_two_pi = { inline const NUMBER init_q_two_pi = {
1, 1,
6, 6,
0, 0,
{ 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,} { 1288380402, 1120116153, 1860424692, 1944118326, 1583591604, 2,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_pi_over_two = { inline const NUMBER init_p_pi_over_two = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
NUMBER init_q_pi_over_two = { inline const NUMBER init_q_pi_over_two = {
1, 1,
6, 6,
0, 0,
{ 429277156, 92748659, 1573365737, 1740753005, 1019699561, 5,} { 429277156, 92748659, 1573365737, 1740753005, 1019699561, 5,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_one_pt_five_pi = { inline const NUMBER init_p_one_pt_five_pi = {
1, 1,
6, 6,
0, 0,
{ 1241201312, 270061909, 1051574664, 1924965045, 1340320627, 70,} { 1241201312, 270061909, 1051574664, 1924965045, 1340320627, 70,}
}; };
NUMBER init_q_one_pt_five_pi = { inline const NUMBER init_q_one_pt_five_pi = {
1, 1,
6, 6,
0, 0,
{ 1579671539, 1837970263, 1067644340, 523549916, 2119366659, 14,} { 1579671539, 1837970263, 1067644340, 523549916, 2119366659, 14,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_e_to_one_half = { inline const NUMBER init_p_e_to_one_half = {
1, 1,
6, 6,
0, 0,
{ 256945612, 216219427, 223516738, 477442596, 581063757, 23,} { 256945612, 216219427, 223516738, 477442596, 581063757, 23,}
}; };
NUMBER init_q_e_to_one_half = { inline const NUMBER init_q_e_to_one_half = {
1, 1,
6, 6,
0, 0,
{ 1536828363, 698484484, 1127331835, 224219346, 245499408, 14,} { 1536828363, 698484484, 1127331835, 224219346, 245499408, 14,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_exp = { inline const NUMBER init_p_rat_exp = {
1, 1,
6, 6,
0, 0,
{ 943665199, 1606559160, 1094967530, 1759391384, 1671799163, 1123581,} { 943665199, 1606559160, 1094967530, 1759391384, 1671799163, 1123581,}
}; };
NUMBER init_q_rat_exp = { inline const NUMBER init_q_rat_exp = {
1, 1,
6, 6,
0, 0,
{ 879242208, 2022880100, 617392930, 1374929092, 1367479163, 413342,} { 879242208, 2022880100, 617392930, 1374929092, 1367479163, 413342,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_ln_ten = { inline const NUMBER init_p_ln_ten = {
1, 1,
6, 6,
0, 0,
{ 2086268922, 165794492, 1416063951, 1851428830, 1893239400, 65366841,} { 2086268922, 165794492, 1416063951, 1851428830, 1893239400, 65366841,}
}; };
NUMBER init_q_ln_ten = { inline const NUMBER init_q_ln_ten = {
1, 1,
6, 6,
0, 0,
{ 26790652, 564532679, 783998273, 216030448, 1564709968, 28388458,} { 26790652, 564532679, 783998273, 216030448, 1564709968, 28388458,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_ln_two = { inline const NUMBER init_p_ln_two = {
1, 1,
6, 6,
0, 0,
{ 1789230241, 1057927868, 715399197, 908801241, 1411265331, 3,} { 1789230241, 1057927868, 715399197, 908801241, 1411265331, 3,}
}; };
NUMBER init_q_ln_two = { inline const NUMBER init_q_ln_two = {
1, 1,
6, 6,
0, 0,
{ 1559869847, 1930657510, 1228561531, 219003871, 593099283, 5,} { 1559869847, 1930657510, 1228561531, 219003871, 593099283, 5,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rad_to_deg = { inline const NUMBER init_p_rad_to_deg = {
1, 1,
6, 6,
0, 0,
{ 2127722024, 1904928383, 2016479213, 2048947859, 1578647346, 492,} { 2127722024, 1904928383, 2016479213, 2048947859, 1578647346, 492,}
}; };
NUMBER init_q_rad_to_deg = { inline const NUMBER init_q_rad_to_deg = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rad_to_grad = { inline const NUMBER init_p_rad_to_grad = {
1, 1,
6, 6,
0, 0,
{ 2125526288, 684931327, 570267400, 129125085, 1038224725, 547,} { 2125526288, 684931327, 570267400, 129125085, 1038224725, 547,}
}; };
NUMBER init_q_rad_to_grad = { inline const NUMBER init_q_rad_to_grad = {
1, 1,
6, 6,
0, 0,
{ 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,} { 125527896, 283898350, 1960493936, 1672850762, 1288168272, 8,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_qword = { inline const NUMBER init_p_rat_qword = {
1, 1,
3, 3,
0, 0,
{ 2147483647, 2147483647, 3,} { 2147483647, 2147483647, 3,}
}; };
NUMBER init_q_rat_qword = { inline const NUMBER init_q_rat_qword = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_dword = { inline const NUMBER init_p_rat_dword = {
1, 1,
2, 2,
0, 0,
{ 2147483647, 1,} { 2147483647, 1,}
}; };
NUMBER init_q_rat_dword = { inline const NUMBER init_q_rat_dword = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_max_long = { inline const NUMBER init_p_rat_max_long = {
1, 1,
1, 1,
0, 0,
{ 2147483647,} { 2147483647,}
}; };
NUMBER init_q_rat_max_long = { inline const NUMBER init_q_rat_max_long = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_min_long = { inline const NUMBER init_p_rat_min_long = {
-1, -1,
2, 2,
0, 0,
{ 0, 1,} { 0, 1,}
}; };
NUMBER init_q_rat_min_long = { inline const NUMBER init_q_rat_min_long = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_word = { inline const NUMBER init_p_rat_word = {
1, 1,
1, 1,
0, 0,
{ 65535,} { 65535,}
}; };
NUMBER init_q_rat_word = { inline const NUMBER init_q_rat_word = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_byte = { inline const NUMBER init_p_rat_byte = {
1, 1,
1, 1,
0, 0,
{ 255,} { 255,}
}; };
NUMBER init_q_rat_byte = { inline const NUMBER init_q_rat_byte = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_400 = { inline const NUMBER init_p_rat_400 = {
1, 1,
1, 1,
0, 0,
{ 400,} { 400,}
}; };
NUMBER init_q_rat_400 = { inline const NUMBER init_q_rat_400 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_360 = { inline const NUMBER init_p_rat_360 = {
1, 1,
1, 1,
0, 0,
{ 360,} { 360,}
}; };
NUMBER init_q_rat_360 = { inline const NUMBER init_q_rat_360 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_200 = { inline const NUMBER init_p_rat_200 = {
1, 1,
1, 1,
0, 0,
{ 200,} { 200,}
}; };
NUMBER init_q_rat_200 = { inline const NUMBER init_q_rat_200 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_180 = { inline const NUMBER init_p_rat_180 = {
1, 1,
1, 1,
0, 0,
{ 180,} { 180,}
}; };
NUMBER init_q_rat_180 = { inline const NUMBER init_q_rat_180 = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_max_exp = { inline const NUMBER init_p_rat_max_exp = {
1, 1,
1, 1,
0, 0,
{ 100000,} { 100000,}
}; };
NUMBER init_q_rat_max_exp = { inline const NUMBER init_q_rat_max_exp = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_min_exp = { inline const NUMBER init_p_rat_min_exp = {
-1, -1,
1, 1,
0, 0,
{ 100000,} { 100000,}
}; };
NUMBER init_q_rat_min_exp = { inline const NUMBER init_q_rat_min_exp = {
1, 1,
1, 1,
0, 0,
{ 1,} { 1,}
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_max_fact = { inline const NUMBER init_p_rat_max_fact = {
1, 1,
1, 1,
0, 0,
{ 3249, } { 3249, }
}; };
NUMBER init_q_rat_max_fact = { inline const NUMBER init_q_rat_max_fact = {
1, 1,
1, 1,
0, 0,
{ 1, } { 1, }
}; };
// Autogenerated by _dumprawrat in support.c // Autogenerated by _dumprawrat in support.cpp
NUMBER init_p_rat_min_fact = { inline const NUMBER init_p_rat_min_fact = {
-1, -1,
1, 1,
0, 0,
{ 1000, } { 1000, }
}; };
NUMBER init_q_rat_min_fact = { inline const NUMBER init_q_rat_min_fact = {
1, 1,
1, 1,
0, 0,

View file

@ -411,7 +411,7 @@ extern void tanrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
// angle type // angle type
extern void tananglerat( _Inout_ PRAT *px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision); extern void tananglerat( _Inout_ PRAT *px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
extern void _dupnum(_In_ PNUMBER dest, _In_ PNUMBER src); extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src);
extern void _destroynum( _In_ PNUMBER pnum ); extern void _destroynum( _In_ PNUMBER pnum );
extern void _destroyrat( _In_ PRAT prat ); extern void _destroyrat( _In_ PRAT prat );
@ -424,7 +424,7 @@ extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision);
extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision); extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision);
extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision); extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision);
extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b ); extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b );
extern void gcdrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision); extern void gcdrat( _Inout_ PRAT *pa, int32_t precision);
extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix);
extern void mulnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b ); extern void mulnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b );

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -31,8 +31,8 @@ static int cbitsofprecision = 0;
#define READRAWNUM(v) #define READRAWNUM(v)
#define DUMPRAWRAT(v) _dumprawrat(#v,v, wcout) #define DUMPRAWRAT(v) _dumprawrat(#v,v, wcout)
#define DUMPRAWNUM(v) fprintf( stderr, \ #define DUMPRAWNUM(v) fprintf( stderr, \
"// Autogenerated by _dumprawrat in support.c\n" ); \ "// Autogenerated by _dumprawrat in support.cpp\n" ); \
fprintf( stderr, "NUMBER init_" #v "= {\n" ); \ fprintf( stderr, "inline const NUMBER init_" #v "= {\n" ); \
_dumprawnum(v, wcout); \ _dumprawnum(v, wcout); \
fprintf( stderr, "};\n" ) fprintf( stderr, "};\n" )
@ -58,7 +58,7 @@ static int cbitsofprecision = RATIO_FOR_DECIMAL * DECIMAL * CALC_DECIMAL_DIGITS_
#endif #endif
bool g_ftrueinfinite = false; // Set to true if you don't want bool g_ftrueinfinite = false; // Set to true if you don't want
// chopping internally // chopping internally
// precision used internally // precision used internally
@ -119,8 +119,8 @@ PRAT rat_max_long= nullptr; // max signed long
void ChangeConstants(uint32_t radix, int32_t precision) void ChangeConstants(uint32_t radix, int32_t precision)
{ {
// ratio is set to the number of digits in the current radix, you can get // ratio is set to the number of digits in the current radix, you can get
// in the internal BASEX radix, this is important for length calculations // in the internal BASEX radix, this is important for length calculations
// in translating from radix to BASEX and back. // in translating from radix to BASEX and back.
uint64_t limit = static_cast<uint64_t>(BASEX) / static_cast<uint64_t>(radix); uint64_t limit = static_cast<uint64_t>(BASEX) / static_cast<uint64_t>(radix);
@ -213,7 +213,7 @@ void ChangeConstants(uint32_t radix, int32_t precision)
cbitsofprecision = g_ratio * radix * precision; cbitsofprecision = g_ratio * radix * precision;
// Apparently when dividing 180 by pi, another (internal) digit of // Apparently when dividing 180 by pi, another (internal) digit of
// precision is needed. // precision is needed.
long extraPrecision = precision + g_ratio; long extraPrecision = precision + g_ratio;
DUPRAT(pi, rat_half); DUPRAT(pi, rat_half);
@ -348,7 +348,7 @@ bool rat_ge( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( zernum( rattmp->pp ) || bool bret = ( zernum( rattmp->pp ) ||
rattmp->pp->sign * rattmp->pq->sign == 1 ); rattmp->pp->sign * rattmp->pq->sign == 1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
@ -472,10 +472,10 @@ void scale( PRAT *px, PRAT scalefact, uint32_t radix, int32_t precision )
{ {
PRAT pret = nullptr; PRAT pret = nullptr;
DUPRAT(pret,*px); DUPRAT(pret,*px);
// Logscale is a quick way to tell how much extra precision is needed for // Logscale is a quick way to tell how much extra precision is needed for
// scaling by scalefact. // scaling by scalefact.
long logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - long logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) -
(pret->pq->cdigit+pret->pq->exp) ); (pret->pq->cdigit+pret->pq->exp) );
if ( logscale > 0 ) if ( logscale > 0 )
{ {
@ -508,9 +508,9 @@ void scale2pi( PRAT *px, uint32_t radix, int32_t precision )
PRAT my_two_pi = nullptr; PRAT my_two_pi = nullptr;
DUPRAT(pret,*px); DUPRAT(pret,*px);
// Logscale is a quick way to tell how much extra precision is needed for // Logscale is a quick way to tell how much extra precision is needed for
// scaling by 2 pi. // scaling by 2 pi.
long logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - long logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) -
(pret->pq->cdigit+pret->pq->exp) ); (pret->pq->cdigit+pret->pq->exp) );
if ( logscale > 0 ) if ( logscale > 0 )
{ {
@ -663,16 +663,16 @@ void _readconstants( void )
// ARGUMENTS: PRAT *px, long precision // ARGUMENTS: PRAT *px, long precision
// //
// //
// DESCRIPTION: Chops off digits from rational numbers to avoid time // DESCRIPTION: Chops off digits from rational numbers to avoid time
// explosions in calculations of functions using series. // explosions in calculations of functions using series.
// It can be shown that it is enough to only keep the first n digits // It can be shown that it is enough to only keep the first n digits
// of the largest of p or q in the rational p over q form, and of course // of the largest of p or q in the rational p over q form, and of course
// scale the smaller by the same number of digits. This will give you // scale the smaller by the same number of digits. This will give you
// n-1 digits of accuracy. This dramatically speeds up calculations // n-1 digits of accuracy. This dramatically speeds up calculations
// involving hundreds of digits or more. // involving hundreds of digits or more.
// The last part of this trim dealing with exponents never affects accuracy // The last part of this trim dealing with exponents never affects accuracy
// //
// RETURN: none, modifies the pointed to PRAT // RETURN: none, modifies the pointed to PRAT
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -680,7 +680,7 @@ void trimit( PRAT *px, int32_t precision)
{ {
if ( !g_ftrueinfinite ) if ( !g_ftrueinfinite )
{ {
long trim; long trim;
PNUMBER pp=(*px)->pp; PNUMBER pp=(*px)->pp;
PNUMBER pq=(*px)->pq; PNUMBER pq=(*px)->pq;

View file

@ -47,8 +47,8 @@ void scalerat( _Inout_ PRAT *pa, ANGLE_TYPE angletype, uint32_t radix, int32_t p
// EXPLANATION: This uses Taylor series // EXPLANATION: This uses Taylor series
// //
// n // n
// ___ 2j+1 // ___ 2j+1
// \ ] j X // \ ] j X
// \ -1 * --------- // \ -1 * ---------
// / (2j+1)! // / (2j+1)!
// /__] // /__]
@ -73,7 +73,7 @@ void _sinrat( PRAT *px, int32_t precision)
{ {
CREATETAYLOR(); CREATETAYLOR();
DUPRAT(pret,*px); DUPRAT(pret,*px);
DUPRAT(thisterm,*px); DUPRAT(thisterm,*px);
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
@ -84,11 +84,11 @@ void _sinrat( PRAT *px, int32_t precision)
} while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); } while ( !SMALL_ENOUGH_RAT( thisterm, precision) );
DESTROYTAYLOR(); DESTROYTAYLOR();
// Since *px might be epsilon above 1 or below -1, due to TRIMIT we need // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need
// this trick here. // this trick here.
inbetween(px, rat_one, precision); inbetween(px, rat_one, precision);
// Since *px might be epsilon near zero we must set it to zero. // Since *px might be epsilon near zero we must set it to zero.
if ( rat_le(*px, rat_smallest, precision) && rat_ge(*px, rat_negsmallest, precision) ) if ( rat_le(*px, rat_smallest, precision) && rat_ge(*px, rat_negsmallest, precision) )
{ {
@ -166,13 +166,13 @@ void _cosrat( PRAT *px, uint32_t radix, int32_t precision)
CREATETAYLOR(); CREATETAYLOR();
destroynum(pret->pp); destroynum(pret->pp);
destroynum(pret->pq); destroynum(pret->pq);
pret->pp=longtonum( 1L, radix); pret->pp=longtonum( 1L, radix);
pret->pq=longtonum( 1L, radix); pret->pq=longtonum( 1L, radix);
DUPRAT(thisterm,pret) DUPRAT(thisterm,pret)
n2=longtonum(0L, radix); n2=longtonum(0L, radix);
xx->pp->sign *= -1; xx->pp->sign *= -1;
@ -181,7 +181,7 @@ void _cosrat( PRAT *px, uint32_t radix, int32_t precision)
} while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); } while ( !SMALL_ENOUGH_RAT( thisterm, precision) );
DESTROYTAYLOR(); DESTROYTAYLOR();
// Since *px might be epsilon above 1 or below -1, due to TRIMIT we need // Since *px might be epsilon above 1 or below -1, due to TRIMIT we need
// this trick here. // this trick here.
inbetween(px, rat_one, precision); inbetween(px, rat_one, precision);
// Since *px might be epsilon near zero we must set it to zero. // Since *px might be epsilon near zero we must set it to zero.

View file

@ -80,7 +80,7 @@ void _sinhrat( PRAT *px, int32_t precision)
CREATETAYLOR(); CREATETAYLOR();
DUPRAT(pret,*px); DUPRAT(pret,*px);
DUPRAT(thisterm,pret); DUPRAT(thisterm,pret);
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
@ -194,7 +194,7 @@ void coshrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
_coshrat( px, radix, precision); _coshrat( px, radix, precision);
} }
// Since *px might be epsilon below 1 due to TRIMIT // Since *px might be epsilon below 1 due to TRIMIT
// we need this trick here. // we need this trick here.
if ( rat_lt(*px, rat_one, precision) ) if ( rat_lt(*px, rat_one, precision) )
{ {

View file

@ -46,7 +46,7 @@ UnitConverter::UnitConverter(_In_ const shared_ptr<IConverterDataLoader>& dataLo
{ {
m_dataLoader = dataLoader; m_dataLoader = dataLoader;
m_currencyDataLoader = currencyDataLoader; m_currencyDataLoader = currencyDataLoader;
//declaring the delimiter character conversion map // declaring the delimiter character conversion map
quoteConversions[L'|'] = L"{p}"; quoteConversions[L'|'] = L"{p}";
quoteConversions[L'['] = L"{lc}"; quoteConversions[L'['] = L"{lc}";
quoteConversions[L']'] = L"{rc}"; quoteConversions[L']'] = L"{rc}";
@ -90,7 +90,7 @@ vector<Category> UnitConverter::GetCategories()
} }
/// <summary> /// <summary>
/// Sets the current category in use by this converter, /// Sets the current category in use by this converter,
/// and returns a list of unit types that exist under the given category. /// and returns a list of unit types that exist under the given category.
/// </summary> /// </summary>
/// <param name="input">Category struct which we are setting</param> /// <param name="input">Category struct which we are setting</param>
@ -170,7 +170,7 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType
/// <summary> /// <summary>
/// Switches the active field, indicating that we are now entering data into /// Switches the active field, indicating that we are now entering data into
/// what was originally the return field, and storing results into what was /// what was originally the return field, and storing results into what was
/// originally the current field. We swap appropriate values, /// originally the current field. We swap appropriate values,
/// but do not callback, as values have not changed. /// but do not callback, as values have not changed.
/// </summary> /// </summary>
/// <param name="newValue"> /// <param name="newValue">
@ -302,8 +302,8 @@ wstring UnitConverter::Serialize()
out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter; out << std::to_wstring(m_currentHasDecimal) << delimiter << std::to_wstring(m_returnHasDecimal) << delimiter << std::to_wstring(m_switchedActive) << delimiter;
out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|"; out << m_currentDisplay << delimiter << m_returnDisplay << delimiter << "|";
wstringstream categoryString(wstringstream::out); wstringstream categoryString(wstringstream::out);
wstringstream categoryToUnitString(wstringstream::out);; wstringstream categoryToUnitString(wstringstream::out);
wstringstream unitToUnitToDoubleString(wstringstream::out);; wstringstream unitToUnitToDoubleString(wstringstream::out);
for (const Category& c : m_categories) for (const Category& c : m_categories)
{ {
categoryString << CategoryToString(c, delimiter) << ","; categoryString << CategoryToString(c, delimiter) << ",";
@ -420,7 +420,7 @@ void UnitConverter::RestoreUserPreferences(const wstring& userPreferences)
/// <summary> /// <summary>
/// Serializes the Category and Associated Units in the converter and returns it as a string /// Serializes the Category and Associated Units in the converter and returns it as a string
/// </summary> /// </summary>
wstring UnitConverter::SaveUserPreferences() wstring UnitConverter::SaveUserPreferences()
{ {
wstringstream out(wstringstream::out); wstringstream out(wstringstream::out);
@ -441,7 +441,7 @@ wstring UnitConverter::Quote(const wstring& s)
{ {
wstringstream quotedString(wstringstream::out); wstringstream quotedString(wstringstream::out);
//Iterate over the delimiter characters we need to quote // Iterate over the delimiter characters we need to quote
wstring::const_iterator cursor = s.begin(); wstring::const_iterator cursor = s.begin();
while(cursor != s.end()) while(cursor != s.end())
{ {
@ -479,7 +479,7 @@ wstring UnitConverter::Unquote(const wstring& s)
} }
if (cursor == s.end()) if (cursor == s.end())
{ {
//badly formatted // Badly formatted
break; break;
} }
else else
@ -505,7 +505,7 @@ void UnitConverter::SendCommand(Command command)
{ {
if (CheckLoad()) if (CheckLoad())
{ {
//TODO: Localization of characters // TODO: Localization of characters
bool clearFront = false; bool clearFront = false;
if (m_currentDisplay == L"0") if (m_currentDisplay == L"0")
{ {
@ -625,7 +625,7 @@ void UnitConverter::SendCommand(Command command)
default: default:
break; break;
} }
if (clearFront) if (clearFront)
{ {
@ -728,7 +728,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
vector<SuggestedValueIntermediate> intermediateVector; vector<SuggestedValueIntermediate> intermediateVector;
vector<SuggestedValueIntermediate> intermediateWhimsicalVector; vector<SuggestedValueIntermediate> intermediateWhimsicalVector;
unordered_map<Unit, ConversionData, UnitHash> ratios = m_ratioMap[m_fromType]; unordered_map<Unit, ConversionData, UnitHash> ratios = m_ratioMap[m_fromType];
//Calculate converted values for every other unit type in this category, along with their magnitude // Calculate converted values for every other unit type in this category, along with their magnitude
for (const auto& cur : ratios) for (const auto& cur : ratios)
{ {
if (cur.first != m_fromType && cur.first != m_toType) if (cur.first != m_fromType && cur.first != m_toType)
@ -745,21 +745,21 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
} }
} }
//Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value // Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
sort(intermediateVector.begin(), intermediateVector.end(), [] sort(intermediateVector.begin(), intermediateVector.end(), []
(SuggestedValueIntermediate first, SuggestedValueIntermediate second) (SuggestedValueIntermediate first, SuggestedValueIntermediate second)
{ {
if (abs(first.magnitude) == abs(second.magnitude)) if (abs(first.magnitude) == abs(second.magnitude))
{ {
return first.magnitude > second.magnitude; return first.magnitude > second.magnitude;
} }
else else
{ {
return abs(first.magnitude) < abs(second.magnitude); return abs(first.magnitude) < abs(second.magnitude);
} }
}); });
//Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings // Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings
for (const auto& entry : intermediateVector) for (const auto& entry : intermediateVector)
{ {
wstring roundedString; wstring roundedString;
@ -783,7 +783,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
} }
// The Whimsicals are determined differently // The Whimsicals are determined differently
//Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value // Sort the resulting list by absolute magnitude, breaking ties by choosing the positive value
sort(intermediateWhimsicalVector.begin(), intermediateWhimsicalVector.end(), [] sort(intermediateWhimsicalVector.begin(), intermediateWhimsicalVector.end(), []
(SuggestedValueIntermediate first, SuggestedValueIntermediate second) (SuggestedValueIntermediate first, SuggestedValueIntermediate second)
{ {
@ -797,7 +797,7 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
} }
}); });
//Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings // Now that the list is sorted, iterate over it and populate the return vector with properly rounded and formatted return strings
vector<tuple<wstring, Unit>> whimsicalReturnVector; vector<tuple<wstring, Unit>> whimsicalReturnVector;
for (const auto& entry : intermediateWhimsicalVector) for (const auto& entry : intermediateWhimsicalVector)

View file

@ -51,7 +51,7 @@ namespace UnitConversionManager
// null checks. // null checks.
// //
// unitId, name, abbreviation, isConversionSource, isConversionTarget, isWhimsical // unitId, name, abbreviation, isConversionSource, isConversionTarget, isWhimsical
const Unit EMPTY_UNIT = Unit{ -1, L"", L"", true, true, false }; inline const Unit EMPTY_UNIT = Unit{ -1, L"", L"", true, true, false };
struct Category struct Category
{ {

View file

@ -12,6 +12,7 @@
#include <winerror.h> #include <winerror.h>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <iterator>
#include <string> #include <string>
#include <memory> #include <memory>
#include <vector> #include <vector>

View file

@ -154,6 +154,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -172,6 +174,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -190,6 +194,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -208,6 +214,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -226,6 +234,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -244,6 +254,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -262,6 +274,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -280,6 +294,8 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4453</DisableSpecificWarnings> <DisableSpecificWarnings>4453</DisableSpecificWarnings>
<AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/bigobj /await /std:c++17 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View file

@ -3,9 +3,9 @@
#pragma once #pragma once
namespace CalculatorApp { namespace Common namespace CalculatorApp { namespace Common
{ {
ref class AlwaysSelectedCollectionView sealed: ref class AlwaysSelectedCollectionView sealed:
public Windows::UI::Xaml::DependencyObject, public Windows::UI::Xaml::DependencyObject,
public Windows::UI::Xaml::Data::ICollectionView public Windows::UI::Xaml::Data::ICollectionView
{ {
@ -14,11 +14,11 @@ namespace CalculatorApp { namespace Common
m_currentPosition(-1) m_currentPosition(-1)
{ {
m_source = source; m_source = source;
Windows::UI::Xaml::Interop::IBindableObservableVector^ observable = dynamic_cast<Windows::UI::Xaml::Interop::IBindableObservableVector^>(source); Windows::UI::Xaml::Interop::IBindableObservableVector^ observable = dynamic_cast<Windows::UI::Xaml::Interop::IBindableObservableVector^>(source);
if (observable) if (observable)
{ {
observable->VectorChanged += observable->VectorChanged +=
ref new Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler(this, &AlwaysSelectedCollectionView::OnSourceBindableVectorChanged); ref new Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler(this, &AlwaysSelectedCollectionView::OnSourceBindableVectorChanged);
} }
} }
@ -53,7 +53,7 @@ namespace CalculatorApp { namespace Common
return ref new Platform::Collections::Vector<Platform::Object^>(); return ref new Platform::Collections::Vector<Platform::Object^>();
} }
} }
property bool HasMoreItems property bool HasMoreItems
{ {
virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::HasMoreItems::get virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::HasMoreItems::get
{ {
@ -77,7 +77,7 @@ namespace CalculatorApp { namespace Common
} }
// The item is not in the collection // The item is not in the collection
// We're going to schedule a call back later so we // We're going to schedule a call back later so we
// restore the selection to the way we wanted it to begin with // restore the selection to the way we wanted it to begin with
if (m_currentPosition >= 0 && m_currentPosition < static_cast<int>(m_source->Size)) if (m_currentPosition >= 0 && m_currentPosition < static_cast<int>(m_source->Size))
{ {
@ -161,7 +161,7 @@ namespace CalculatorApp { namespace Common
m_currentChanging -= token; m_currentChanging -= token;
} }
} }
// IVector<Object^> // IVector<Object^>
// Not implemented methods // Not implemented methods
virtual void Append(Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::Append virtual void Append(Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::Append
@ -219,7 +219,7 @@ namespace CalculatorApp { namespace Common
return m_source->Size; return m_source->Size;
} }
} }
// IObservableVector<Object^> // IObservableVector<Object^>
event Windows::Foundation::Collections::VectorChangedEventHandler<Platform::Object^>^ VectorChanged event Windows::Foundation::Collections::VectorChangedEventHandler<Platform::Object^>^ VectorChanged
{ {
@ -262,9 +262,9 @@ namespace CalculatorApp { namespace Common
private: private:
virtual Platform::Object^ Convert( virtual Platform::Object^ Convert(
Platform::Object^ value, Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/, Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{ {
auto result = dynamic_cast<Windows::UI::Xaml::Interop::IBindableVector^>(value); auto result = dynamic_cast<Windows::UI::Xaml::Interop::IBindableVector^>(value);
@ -276,9 +276,9 @@ namespace CalculatorApp { namespace Common
} }
virtual Platform::Object^ ConvertBack( virtual Platform::Object^ ConvertBack(
Platform::Object^ /*value*/, Platform::Object^ /*value*/,
Windows::UI::Xaml::Interop::TypeName /*targetType*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/, Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{ {
return Windows::UI::Xaml::DependencyProperty::UnsetValue; return Windows::UI::Xaml::DependencyProperty::UnsetValue;

View file

@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once
#include "pch.h" #include "pch.h"
#include "AppResourceProvider.h" #include "AppResourceProvider.h"

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
@ -20,6 +20,8 @@ namespace CalculatorApp::Common::Automation
StringReference CategoryNameChanged(L"CategoryNameChanged"); StringReference CategoryNameChanged(L"CategoryNameChanged");
StringReference UpdateCurrencyRates(L"UpdateCurrencyRates"); StringReference UpdateCurrencyRates(L"UpdateCurrencyRates");
StringReference DisplayCopied(L"DisplayCopied"); StringReference DisplayCopied(L"DisplayCopied");
StringReference OpenParenthesisCountChanged(L"OpenParenthesisCountChanged");
StringReference NoParenthesisAdded(L"NoParenthesisAdded");
} }
} }
@ -142,3 +144,21 @@ NarratorAnnouncement^ CalculatorAnnouncement::GetDisplayCopiedAnnouncement(Strin
AutomationNotificationKind::ActionCompleted, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent); AutomationNotificationProcessing::ImportantMostRecent);
} }
NarratorAnnouncement^ CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(String^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::OpenParenthesisCountChanged,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(String^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::NoParenthesisAdded,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
@ -88,7 +88,10 @@ namespace CalculatorApp::Common::Automation
static NarratorAnnouncement^ GetCategoryNameChangedAnnouncement(Platform::String^ announcement); static NarratorAnnouncement^ GetCategoryNameChangedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetUpdateCurrencyRatesAnnouncement(Platform::String^ announcement); static NarratorAnnouncement^ GetUpdateCurrencyRatesAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetDisplayCopiedAnnouncement(Platform::String^ announcement); static NarratorAnnouncement^ GetDisplayCopiedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetOpenParenthesisCountChangedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetNoRightParenthesisAddedAnnouncement(Platform::String ^ announcement);
}; };
} }

View file

@ -18,17 +18,17 @@ void BindableBase::OnPropertyChanged(String^ propertyName)
PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName)); PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
} }
Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetCustomProperty(Platform::String^ name) Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetCustomProperty(Platform::String^ name)
{ {
return nullptr; return nullptr;
} }
Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type) Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type)
{ {
return nullptr; return nullptr;
} }
Platform::String^ BindableBase::GetStringRepresentation() Platform::String^ BindableBase::GetStringRepresentation()
{ {
return this->ToString(); return this->ToString();
} }

View file

@ -80,7 +80,7 @@ namespace CalculatorApp
D = (int) CM::Command::CommandD, D = (int) CM::Command::CommandD,
E = (int) CM::Command::CommandE, E = (int) CM::Command::CommandE,
F = (int) CM::Command::CommandF, F = (int) CM::Command::CommandF,
Memory, // This is the memory button. Doesn't have a direct mapping to the CalcEngine. Memory, // This is the memory button. Doesn't have a direct mapping to the CalcEngine.
Sinh = (int) CM::Command::CommandSINH, Sinh = (int) CM::Command::CommandSINH,
Cosh = (int) CM::Command::CommandCOSH, Cosh = (int) CM::Command::CommandCOSH,
Tanh = (int) CM::Command::CommandTANH, Tanh = (int) CM::Command::CommandTANH,

View file

@ -2,7 +2,7 @@
// Licensed under the MIT License. // Licensed under the MIT License.
// This class provides the concrete implementation for the ICalcDisplay interface // This class provides the concrete implementation for the ICalcDisplay interface
// that is declared in the Calculation Manager Library. // that is declared in the Calculation Manager Library.
#include "pch.h" #include "pch.h"
#include "CalculatorDisplay.h" #include "CalculatorDisplay.h"
#include "StandardCalculatorViewModel.h" #include "StandardCalculatorViewModel.h"
@ -29,8 +29,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue
{ {
if (m_callbackReference) if (m_callbackReference)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetPrimaryDisplay(displayStringValue, isError); calcVM->SetPrimaryDisplay(displayStringValue, isError);
} }
@ -41,20 +40,29 @@ void CalculatorDisplay::SetParenDisplayText(_In_ const std::wstring& parenthesis
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetParenthesisCount(parenthesisCount); calcVM->SetParenthesisCount(parenthesisCount);
} }
} }
} }
void CalculatorDisplay::OnNoRightParenAdded()
{
if (m_callbackReference != nullptr)
{
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
{
calcVM->OnNoRightParenAdded();
}
}
}
void CalculatorDisplay::SetIsInError(bool isError) void CalculatorDisplay::SetIsInError(bool isError)
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->IsInError = isError; calcVM->IsInError = isError;
} }
@ -65,8 +73,7 @@ void CalculatorDisplay::SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorV
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if(auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetExpressionDisplay(tokens, commands); calcVM->SetExpressionDisplay(tokens, commands);
} }
@ -77,8 +84,7 @@ void CalculatorDisplay::SetMemorizedNumbers(_In_ const vector<std::wstring>& new
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->SetMemorizedNumbers(newMemorizedNumbers); calcVM->SetMemorizedNumbers(newMemorizedNumbers);
} }
@ -89,8 +95,7 @@ void CalculatorDisplay::OnHistoryItemAdded(_In_ unsigned int addedItemIndex)
{ {
if (m_historyCallbackReference != nullptr) if (m_historyCallbackReference != nullptr)
{ {
auto historyVM = m_historyCallbackReference.Resolve<ViewModel::HistoryViewModel>(); if (auto historyVM = m_historyCallbackReference.Resolve<ViewModel::HistoryViewModel>())
if (historyVM)
{ {
historyVM->OnHistoryItemAdded(addedItemIndex); historyVM->OnHistoryItemAdded(addedItemIndex);
} }
@ -101,8 +106,7 @@ void CalculatorDisplay::MaxDigitsReached()
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->OnMaxDigitsReached(); calcVM->OnMaxDigitsReached();
} }
@ -113,8 +117,7 @@ void CalculatorDisplay::BinaryOperatorReceived()
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->OnBinaryOperatorReceived(); calcVM->OnBinaryOperatorReceived();
} }
@ -125,8 +128,7 @@ void CalculatorDisplay::MemoryItemChanged(unsigned int indexOfMemory)
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {
auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>(); if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (calcVM)
{ {
calcVM->OnMemoryItemChanged(indexOfMemory); calcVM->OnMemoryItemChanged(indexOfMemory);
} }

View file

@ -22,6 +22,7 @@ namespace CalculatorApp
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override; void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override;
void OnNoRightParenAdded() override;
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;
void MemoryItemChanged(unsigned int indexOfMemory) override; void MemoryItemChanged(unsigned int indexOfMemory) override;

View file

@ -12,7 +12,7 @@ namespace CalculatorApp
public: public:
ConversionResultTaskHelper(unsigned int delay, const std::function<void()> functionToRun); ConversionResultTaskHelper(unsigned int delay, const std::function<void()> functionToRun);
~ConversionResultTaskHelper(); ~ConversionResultTaskHelper();
private: private:
concurrency::task<void> CompleteAfter(unsigned int timeout); concurrency::task<void> CompleteAfter(unsigned int timeout);

View file

@ -15,7 +15,6 @@ using namespace Windows::Foundation;
using namespace Windows::System; using namespace Windows::System;
using namespace Windows::ApplicationModel::DataTransfer; using namespace Windows::ApplicationModel::DataTransfer;
size_t maxOperandLength;
unsigned long long maxOperandNumber; unsigned long long maxOperandNumber;
String^ CopyPasteManager::supportedFormats[] = String^ CopyPasteManager::supportedFormats[] =
@ -130,17 +129,17 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m
if (pastedText->Length() > MaxPasteableLength) if (pastedText->Length() > MaxPasteableLength)
{ {
// return NoOp to indicate don't paste anything. // return NoOp to indicate don't paste anything.
TraceLogger::GetInstance().LogInvalidInputPasted(L"PastedExpressionSizeGreaterThanMaxAllowed", L"MoreThanMaxInput", mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"PastedExpressionSizeGreaterThanMaxAllowed", mode, programmerNumberBase, bitLengthType);
return StringReference(PasteErrorString); return StringReference(PasteErrorString);
} }
wstring pasteExpression = pastedText->Data(); wstring pasteExpression = pastedText->Data();
// Get english translated expression // Get english translated expression
String^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression); String^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression);
// Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333 // Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333
pasteExpression = Utils::RemoveUnwantedCharsFromWstring(englishString->Data()); pasteExpression = RemoveUnwantedCharsFromWstring(englishString->Data());
// If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste. // If the last character is an = sign, remove it from the pasteExpression to allow evaluating the result on paste.
if (!pasteExpression.empty() && pasteExpression.back() == L'=') if (!pasteExpression.empty() && pasteExpression.back() == L'=')
@ -165,7 +164,7 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m
// validate each operand with patterns for different modes // validate each operand with patterns for different modes
if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType)) if (!ExpressionRegExMatch(operands, mode, modeType, programmerNumberBase, bitLengthType))
{ {
TraceLogger::GetInstance().LogInvalidInputPasted(L"InvalidExpressionForPresentMode", pastedText->Data(), mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"InvalidExpressionForPresentMode", mode, programmerNumberBase, bitLengthType);
return StringReference(PasteErrorString); return StringReference(PasteErrorString);
} }
@ -194,7 +193,7 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
if (operands.size() >= MaxOperandCount) if (operands.size() >= MaxOperandCount)
{ {
TraceLogger::GetInstance().LogInvalidInputPasted(L"OperandCountGreaterThanMaxCount", pasteExpression.c_str(), mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"OperandCountGreaterThanMaxCount", mode, programmerNumberBase, bitLengthType);
operands.clear(); operands.clear();
return operands; return operands;
} }
@ -208,7 +207,7 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
// to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999. // to disallow pasting of 1e+12345 as 1e+1234, max exponent that can be pasted is 9999.
if (expLength > MaxExponentLength) if (expLength > MaxExponentLength)
{ {
TraceLogger::GetInstance().LogInvalidInputPasted(L"ExponentLengthGreaterThanMaxLength", pasteExpression.c_str(), mode, programmerNumberBase, bitLengthType); TraceLogger::GetInstance().LogInvalidPastedInputOccurred(L"ExponentLengthGreaterThanMaxLength", mode, programmerNumberBase, bitLengthType);
operands.clear(); operands.clear();
return operands; return operands;
} }
@ -405,7 +404,7 @@ wstring CopyPasteManager::SanitizeOperand(const wstring& operand)
{ {
wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-' }; wchar_t unWantedChars[] = { L'\'', L'_', L'`', L'(', L')', L'-' };
return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, ARRAYSIZE(unWantedChars)); return Utils::RemoveUnwantedCharsFromWstring(operand, unWantedChars, static_cast<int>(size(unWantedChars)));
} }
bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, unsigned long long int& result) bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, unsigned long long int& result)
@ -533,7 +532,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end()); suffixes.insert(suffixes.end(), uintSuffixes.begin(), uintSuffixes.end());
wstring operandUpper = operand; wstring operandUpper = operand;
transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), toupper); transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper);
// Detect if there is a suffix and subtract its length // Detect if there is a suffix and subtract its length
// Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value). // Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value).
@ -568,3 +567,21 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
return len; return len;
} }
// return wstring after removing characters like space, comma, double quotes, and monetary prefix currency symbols supported by the Windows keyboard:
// yen or yuan(¥) - 165
// unspecified currency sign(¤) - 164
// Ghanaian cedi(₵) - 8373
// dollar or peso($) - 36
// colón(₡) - 8353
// won(₩) - 8361
// shekel(₪) - 8362
// naira(₦) - 8358
// Indian rupee(₹) - 8377
// pound(£) - 163
// euro(€) - 8364
wstring CopyPasteManager::RemoveUnwantedCharsFromWstring(const wstring& input)
{
wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237 };
return Utils::RemoveUnwantedCharsFromWstring(input, unWantedChars, 18);
}

View file

@ -58,6 +58,7 @@ namespace CalculatorApp
static size_t OperandLength(std::wstring operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1); static size_t OperandLength(std::wstring operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1);
static size_t StandardScientificOperandLength(std::wstring operand); static size_t StandardScientificOperandLength(std::wstring operand);
static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase); static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase);
static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input);
static constexpr size_t MaxStandardOperandLength = 16; static constexpr size_t MaxStandardOperandLength = 16;
static constexpr size_t MaxScientificOperandLength = 32; static constexpr size_t MaxScientificOperandLength = 32;

View file

@ -15,7 +15,7 @@ DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier)
m_calendar->ChangeCalendarSystem(calendarIdentifier); m_calendar->ChangeCalendarSystem(calendarIdentifier);
} }
// Adding Duration to a Date // Adding Duration to a Date
// Returns: True if function succeeds to calculate the date else returns False // Returns: True if function succeeds to calculate the date else returns False
bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate) bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate)
{ {
@ -52,7 +52,7 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate) bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate)
{ {
// For Subtract the Algorithm is different than Add. Here the smaller units are subtracted first // For Subtract the Algorithm is different than Add. Here the smaller units are subtracted first
// and then the larger units. // and then the larger units.
try try
{ {
m_calendar->SetDateTime(startDate); m_calendar->SetDateTime(startDate);

View file

@ -21,10 +21,10 @@ namespace CalculatorApp
private: private:
// Explicit, and private, implementation of ICommand, this way of programming makes it so // Explicit, and private, implementation of ICommand, this way of programming makes it so
// the ICommand methods will only be available if the ICommand interface is requested via a dynamic_cast // the ICommand methods will only be available if the ICommand interface is requested via a dynamic_cast
// The ICommand interface is meant to be consumed by Xaml and not by the app, this is a defensive measure against // The ICommand interface is meant to be consumed by Xaml and not by the app, this is a defensive measure against
// code in the app calling Execute. // code in the app calling Execute.
virtual void ExecuteImpl(Platform::Object^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::Execute virtual void ExecuteImpl(Platform::Object^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::Execute
{ {
TTarget^ target = m_weakTarget.Resolve<TTarget>(); TTarget^ target = m_weakTarget.Resolve<TTarget>();

View file

@ -43,7 +43,6 @@ static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyControlS
static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyInverseChordsForButtons; static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyInverseChordsForButtons;
static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyControlInverseChordsForButtons; static multimap<int, multimap<MyVirtualKey, WeakReference>> s_VirtualKeyControlInverseChordsForButtons;
static const TimeSpan c_lightUpTime = { 500000 }; // Quarter of a second
static multimap<int, bool> s_ShiftKeyPressed; static multimap<int, bool> s_ShiftKeyPressed;
static multimap<int, bool> s_ControlKeyPressed; static multimap<int, bool> s_ControlKeyPressed;
static multimap<int, bool> s_ShiftButtonChecked; static multimap<int, bool> s_ShiftButtonChecked;
@ -57,7 +56,7 @@ namespace CalculatorApp
{ {
// Lights up all of the buttons in the given range // Lights up all of the buttons in the given range
// The range is defined by a pair of iterators // The range is defined by a pair of iterators
template <typename T> template <typename T>
void LightUpButtons(const T& buttons) void LightUpButtons(const T& buttons)
{ {
auto iterator = buttons.first; auto iterator = buttons.first;
@ -73,22 +72,24 @@ namespace CalculatorApp
void LightUpButton(ButtonBase^ button) void LightUpButton(ButtonBase^ button)
{ {
// If the button is a toggle button then we don't need // If the button is a toggle button then we don't need
// to change the UI of the button // to change the UI of the button
if (dynamic_cast<ToggleButton^>(button)) if (dynamic_cast<ToggleButton^>(button))
{ {
return; return;
} }
// The button will go into the visual Pressed state with this call // The button will go into the visual Pressed state with this call
VisualStateManager::GoToState(button, "Pressed", true); VisualStateManager::GoToState(button, "Pressed", true);
// This timer will fire after c_lightUpTime and make the button // This timer will fire after lightUpTime and make the button
// go back to the normal state. // go back to the normal state.
// This timer will only fire once after which it will be destroyed // This timer will only fire once after which it will be destroyed
auto timer = ref new DispatcherTimer(); auto timer = ref new DispatcherTimer();
timer->Interval = c_lightUpTime; TimeSpan lightUpTime{};
lightUpTime.Duration = 500000L; // Half second (in 100-ns units)
timer->Interval = lightUpTime;
WeakReference timerWeakReference(timer); WeakReference timerWeakReference(timer);
WeakReference buttonWeakReference(button); WeakReference buttonWeakReference(button);
timer->Tick += ref new EventHandler<Object^>( timer->Tick += ref new EventHandler<Object^>(
@ -205,7 +206,7 @@ void KeyboardShortcutManager::HonorEscape()
} }
void KeyboardShortcutManager::OnCharacterPropertyChanged( void KeyboardShortcutManager::OnCharacterPropertyChanged(
DependencyObject^ target, DependencyObject^ target,
String^ oldValue, String^ oldValue,
String^ newValue) String^ newValue)
{ {
@ -262,10 +263,10 @@ void KeyboardShortcutManager::OnVirtualKeyPropertyChanged(
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto button = static_cast<ButtonBase^>(target); auto button = static_cast<ButtonBase^>(target);
int viewId = Utils::GetWindowId(); int viewId = Utils::GetWindowId();
auto iterViewMap = s_VirtualKeysForButtons.find(viewId); auto iterViewMap = s_VirtualKeysForButtons.find(viewId);
// Check if the View Id has already been registered // Check if the View Id has already been registered
if (iterViewMap != s_VirtualKeysForButtons.end()) if (iterViewMap != s_VirtualKeysForButtons.end())
{ {
@ -280,7 +281,7 @@ void KeyboardShortcutManager::OnVirtualKeyPropertyChanged(
} }
void KeyboardShortcutManager::OnVirtualKeyControlChordPropertyChanged( void KeyboardShortcutManager::OnVirtualKeyControlChordPropertyChanged(
DependencyObject^ target, DependencyObject^ target,
MyVirtualKey /*oldValue*/, MyVirtualKey /*oldValue*/,
MyVirtualKey newValue) MyVirtualKey newValue)
{ {
@ -536,7 +537,7 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
// Handle Ctrl + E for DateCalculator // Handle Ctrl + E for DateCalculator
if ((key == VirtualKey::E) && if ((key == VirtualKey::E) &&
isControlKeyPressed && isControlKeyPressed &&
!isShiftKeyPressed) !isShiftKeyPressed)
{ {
const auto& lookupMap = GetCurrentKeyDictionary(static_cast<MyVirtualKey>(key)); const auto& lookupMap = GetCurrentKeyDictionary(static_cast<MyVirtualKey>(key));
@ -579,9 +580,9 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto currentControlKeyPressed = s_ControlKeyPressed.find(viewId); auto currControlKeyPressed = s_ControlKeyPressed.find(viewId);
if (currentControlKeyPressed != s_ControlKeyPressed.end()) if (currControlKeyPressed != s_ControlKeyPressed.end())
{ {
s_ControlKeyPressed.erase(viewId); s_ControlKeyPressed.erase(viewId);
s_ControlKeyPressed.insert(std::make_pair(viewId, true)); s_ControlKeyPressed.insert(std::make_pair(viewId, true));
@ -593,9 +594,9 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto currentShiftKeyPressed = s_ShiftKeyPressed.find(viewId); auto currShiftKeyPressed = s_ShiftKeyPressed.find(viewId);
if (currentShiftKeyPressed != s_ShiftKeyPressed.end()) if (currShiftKeyPressed != s_ShiftKeyPressed.end())
{ {
s_ShiftKeyPressed.erase(viewId); s_ShiftKeyPressed.erase(viewId);
s_ShiftKeyPressed.insert(std::make_pair(viewId, true)); s_ShiftKeyPressed.insert(std::make_pair(viewId, true));
@ -636,7 +637,7 @@ void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow^ sender, KeyEventArgs^ a
int viewId = Utils::GetWindowId(); int viewId = Utils::GetWindowId();
auto key = args->VirtualKey; auto key = args->VirtualKey;
if (args->VirtualKey == VirtualKey::Shift) if (key == VirtualKey::Shift)
{ {
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
@ -649,14 +650,14 @@ void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow^ sender, KeyEventArgs^ a
s_ShiftKeyPressed.insert(std::make_pair(viewId, false)); s_ShiftKeyPressed.insert(std::make_pair(viewId, false));
} }
} }
else if (args->VirtualKey == VirtualKey::Control) else if (key == VirtualKey::Control)
{ {
// Writer lock for the static maps // Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto currentControlKeyPressed = s_ControlKeyPressed.find(viewId); auto currControlKeyPressed = s_ControlKeyPressed.find(viewId);
if (currentControlKeyPressed != s_ControlKeyPressed.end()) if (currControlKeyPressed != s_ControlKeyPressed.end())
{ {
s_ControlKeyPressed.erase(viewId); s_ControlKeyPressed.erase(viewId);
s_ControlKeyPressed.insert(std::make_pair(viewId, false)); s_ControlKeyPressed.insert(std::make_pair(viewId, false));
@ -709,7 +710,7 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher^, Acceler
{ {
int viewId = Utils::GetWindowId(); int viewId = Utils::GetWindowId();
auto iterViewMap = s_AboutFlyout.find(viewId); auto iterViewMap = s_AboutFlyout.find(viewId);
if ((iterViewMap != s_AboutFlyout.end()) && (iterViewMap->second != nullptr)) if ((iterViewMap != s_AboutFlyout.end()) && (iterViewMap->second != nullptr))
{ {
iterViewMap->second->Hide(); iterViewMap->second->Hide();
@ -720,9 +721,9 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher^, Acceler
void KeyboardShortcutManager::Initialize() void KeyboardShortcutManager::Initialize()
{ {
auto coreWindow = Window::Current->CoreWindow; auto coreWindow = Window::Current->CoreWindow;
coreWindow->CharacterReceived += coreWindow->CharacterReceived +=
ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(&KeyboardShortcutManager::OnCharacterReceivedHandler); ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(&KeyboardShortcutManager::OnCharacterReceivedHandler);
coreWindow->KeyDown += coreWindow->KeyDown +=
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(&KeyboardShortcutManager::OnKeyDownHandler); ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(&KeyboardShortcutManager::OnKeyDownHandler);
coreWindow->KeyUp += coreWindow->KeyUp +=
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(&KeyboardShortcutManager::OnKeyUpHandler); ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(&KeyboardShortcutManager::OnKeyUpHandler);
@ -757,7 +758,7 @@ void KeyboardShortcutManager::UpdateDropDownState(bool isOpen)
void KeyboardShortcutManager::UpdateDropDownState(Flyout^ aboutPageFlyout) void KeyboardShortcutManager::UpdateDropDownState(Flyout^ aboutPageFlyout)
{ {
int viewId = Utils::GetWindowId(); int viewId = Utils::GetWindowId();
if (s_AboutFlyout.find(viewId) != s_AboutFlyout.end()) if (s_AboutFlyout.find(viewId) != s_AboutFlyout.end())
{ {
s_AboutFlyout.erase(viewId); s_AboutFlyout.erase(viewId);
@ -802,7 +803,7 @@ void KeyboardShortcutManager::RegisterNewAppViewId()
{ {
s_CharacterForButtons.insert(std::make_pair(appViewId, std::multimap<wchar_t, WeakReference>())); s_CharacterForButtons.insert(std::make_pair(appViewId, std::multimap<wchar_t, WeakReference>()));
} }
if (s_VirtualKeysForButtons.find(appViewId) == s_VirtualKeysForButtons.end()) if (s_VirtualKeysForButtons.find(appViewId) == s_VirtualKeysForButtons.end())
{ {
s_VirtualKeysForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>())); s_VirtualKeysForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>()));
@ -822,17 +823,17 @@ void KeyboardShortcutManager::RegisterNewAppViewId()
{ {
s_VirtualKeyAltChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>())); s_VirtualKeyAltChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>()));
} }
if (s_VirtualKeyControlShiftChordsForButtons.find(appViewId) == s_VirtualKeyControlShiftChordsForButtons.end()) if (s_VirtualKeyControlShiftChordsForButtons.find(appViewId) == s_VirtualKeyControlShiftChordsForButtons.end())
{ {
s_VirtualKeyControlShiftChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>())); s_VirtualKeyControlShiftChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>()));
} }
if (s_VirtualKeyInverseChordsForButtons.find(appViewId) == s_VirtualKeyInverseChordsForButtons.end()) if (s_VirtualKeyInverseChordsForButtons.find(appViewId) == s_VirtualKeyInverseChordsForButtons.end())
{ {
s_VirtualKeyInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>())); s_VirtualKeyInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>()));
} }
if (s_VirtualKeyControlInverseChordsForButtons.find(appViewId) == s_VirtualKeyControlInverseChordsForButtons.end()) if (s_VirtualKeyControlInverseChordsForButtons.find(appViewId) == s_VirtualKeyControlInverseChordsForButtons.end())
{ {
s_VirtualKeyControlInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>())); s_VirtualKeyControlInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap<MyVirtualKey, WeakReference>()));

View file

@ -206,7 +206,7 @@ FontWeight LocalizationService::GetFontWeightOverride()
double LocalizationService::GetFontScaleFactorOverride(LanguageFontType fontType) double LocalizationService::GetFontScaleFactorOverride(LanguageFontType fontType)
{ {
assert(m_overrideFontApiValues); assert(m_overrideFontApiValues);
switch (fontType) switch (fontType)
{ {
case LanguageFontType::UIText: case LanguageFontType::UIText:
@ -271,12 +271,12 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
{ {
control->FontSize = sizeToUse; control->FontSize = sizeToUse;
} }
else else
{ {
control->ClearValue(Control::FontSizeProperty); control->ClearValue(Control::FontSizeProperty);
} }
} }
else else
{ {
auto textBlock = dynamic_cast<TextBlock^>(target); auto textBlock = dynamic_cast<TextBlock^>(target);
if (textBlock) if (textBlock)
@ -290,7 +290,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
{ {
textBlock->FontSize = sizeToUse; textBlock->FontSize = sizeToUse;
} }
else else
{ {
textBlock->ClearValue(TextBlock::FontSizeProperty); textBlock->ClearValue(TextBlock::FontSizeProperty);
} }
@ -309,7 +309,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
{ {
richTextBlock->FontSize = sizeToUse; richTextBlock->FontSize = sizeToUse;
} }
else else
{ {
richTextBlock->ClearValue(RichTextBlock::FontSizeProperty); richTextBlock->ClearValue(RichTextBlock::FontSizeProperty);
} }
@ -328,7 +328,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
{ {
textElement->FontSize = sizeToUse; textElement->FontSize = sizeToUse;
} }
else else
{ {
textElement->ClearValue(TextElement::FontSizeProperty); textElement->ClearValue(TextElement::FontSizeProperty);
} }
@ -416,7 +416,7 @@ IIterable<String^>^ LocalizationService::GetLanguageIdentifiers()
int result = GetUserDefaultLocaleName(currentLocale, LOCALE_NAME_MAX_LENGTH); int result = GetUserDefaultLocaleName(currentLocale, LOCALE_NAME_MAX_LENGTH);
if (result != 0) if (result != 0)
{ {
// GetUserDefaultLocaleName may return an invalid bcp47 language tag with trailing non-BCP47 friendly characters, // GetUserDefaultLocaleName may return an invalid bcp47 language tag with trailing non-BCP47 friendly characters,
// which if present would start with an underscore, for example sort order // which if present would start with an underscore, for example sort order
// (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd373814(v=vs.85).aspx). // (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd373814(v=vs.85).aspx).
// Therefore, if there is an underscore in the locale name, trim all characters from the underscore onwards. // Therefore, if there is an underscore in the locale name, trim all characters from the underscore onwards.

View file

@ -4,6 +4,8 @@
#pragma once #pragma once
#include "LocalizationService.h" #include "LocalizationService.h"
#include <iterator>
namespace CalculatorApp namespace CalculatorApp
{ {
namespace Common namespace Common
@ -26,8 +28,9 @@ namespace CalculatorApp
m_digitSymbols.at(i) = formatter->FormatUInt(i)->Data()[0]; m_digitSymbols.at(i) = formatter->FormatUInt(i)->Data()[0];
} }
wchar_t resolvedName[LOCALE_NAME_MAX_LENGTH];
result = ResolveLocaleName(formatter->ResolvedLanguage->Data(), result = ResolveLocaleName(formatter->ResolvedLanguage->Data(),
m_resolvedName, resolvedName,
LOCALE_NAME_MAX_LENGTH); LOCALE_NAME_MAX_LENGTH);
if (result == 0) if (result == 0)
{ {
@ -35,31 +38,32 @@ namespace CalculatorApp
} }
else else
{ {
m_resolvedName = resolvedName;
wchar_t decimalString[LocaleSettingBufferSize] = L""; wchar_t decimalString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_SDECIMAL, LOCALE_SDECIMAL,
decimalString, decimalString,
ARRAYSIZE(decimalString)); static_cast<int>(std::size(decimalString)));
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
} }
wchar_t groupingSymbolString[LocaleSettingBufferSize] = L""; wchar_t groupingSymbolString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_STHOUSAND, LOCALE_STHOUSAND,
groupingSymbolString, groupingSymbolString,
ARRAYSIZE(groupingSymbolString)); static_cast<int>(std::size(groupingSymbolString)));
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
} }
wchar_t numberGroupingString[LocaleSettingBufferSize] = L""; wchar_t numberGroupingString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_SGROUPING, LOCALE_SGROUPING,
numberGroupingString, numberGroupingString,
ARRAYSIZE(numberGroupingString)); static_cast<int>(std::size(numberGroupingString)));
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
@ -70,14 +74,14 @@ namespace CalculatorApp
result = ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, result = ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_SLIST, LOCALE_SLIST,
listSeparatorString, listSeparatorString,
ARRAYSIZE(listSeparatorString)); // Max length of the expected return value is 4 static_cast<int>(std::size(listSeparatorString))); // Max length of the expected return value is 4
if (result == 0) if (result == 0)
{ {
throw std::runtime_error("Unexpected error while getting locale info"); throw std::runtime_error("Unexpected error while getting locale info");
} }
int currencyTrailingDigits = 0; int currencyTrailingDigits = 0;
result = GetLocaleInfoEx(m_resolvedName, result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER, LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER,
(LPWSTR)&currencyTrailingDigits, (LPWSTR)&currencyTrailingDigits,
sizeof(currencyTrailingDigits) / sizeof(WCHAR)); sizeof(currencyTrailingDigits) / sizeof(WCHAR));
@ -120,7 +124,7 @@ namespace CalculatorApp
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_IFIRSTDAYOFWEEK, // The first day in a week LOCALE_IFIRSTDAYOFWEEK, // The first day in a week
reinterpret_cast<PWSTR>(day), // Argument is of type PWSTR reinterpret_cast<PWSTR>(day), // Argument is of type PWSTR
ARRAYSIZE(day)); // Max return size are 80 characters static_cast<int>(std::size(day))); // Max return size are 80 characters
// The LOCALE_IFIRSTDAYOFWEEK integer value varies from 0, 1, .. 6 for Monday, Tuesday, ... Sunday // The LOCALE_IFIRSTDAYOFWEEK integer value varies from 0, 1, .. 6 for Monday, Tuesday, ... Sunday
// DayOfWeek enum value varies from 0, 1, .. 6 for Sunday, Monday, ... Saturday // DayOfWeek enum value varies from 0, 1, .. 6 for Sunday, Monday, ... Saturday
@ -147,7 +151,7 @@ namespace CalculatorApp
Platform::String^ GetLocaleName() const Platform::String^ GetLocaleName() const
{ {
return ref new Platform::String(m_resolvedName); return ref new Platform::String(m_resolvedName.c_str());
} }
bool IsDigitEnUsSetting() const bool IsDigitEnUsSetting() const
@ -377,7 +381,7 @@ namespace CalculatorApp
Platform::String^ m_calendarIdentifier; Platform::String^ m_calendarIdentifier;
Windows::Globalization::DayOfWeek m_firstDayOfWeek; Windows::Globalization::DayOfWeek m_firstDayOfWeek;
int m_currencySymbolPrecedence; int m_currencySymbolPrecedence;
wchar_t m_resolvedName[LOCALE_NAME_MAX_LENGTH]; std::wstring m_resolvedName;
int m_currencyTrailingDigits; int m_currencyTrailingDigits;
static const unsigned int LocaleSettingBufferSize = 16; static const unsigned int LocaleSettingBufferSize = 16;
}; };

View file

@ -20,11 +20,11 @@ namespace CalculatorApp
va_list args = NULL; va_list args = NULL;
va_start(args, pMessage); va_start(args, pMessage);
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING,
pMessage, pMessage,
0, 0,
0, 0,
spBuffer.get(), spBuffer.get(),
length, length,
&args); &args);
va_end(args); va_end(args);

View file

@ -141,7 +141,7 @@ namespace CalculatorApp
property Platform::String^ AccessKey property Platform::String^ AccessKey
{ {
Platform::String^ get() Platform::String^ get()
{ {
return m_accessKey; return m_accessKey;
} }
@ -220,11 +220,11 @@ namespace CalculatorApp
static Windows::Foundation::Collections::IObservableVector<NavCategoryGroup^>^ CreateMenuOptions(); static Windows::Foundation::Collections::IObservableVector<NavCategoryGroup^>^ CreateMenuOptions();
static Platform::String^ GetHeaderResourceKey(CategoryGroupType type); static Platform::String^ GetHeaderResourceKey(CategoryGroupType type);
internal: internal:
static NavCategoryGroup^ CreateCalculatorCategory(); static NavCategoryGroup^ CreateCalculatorCategory();
static NavCategoryGroup^ CreateConverterCategory(); static NavCategoryGroup^ CreateConverterCategory();
private: private:
NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer); NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer);

View file

@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once
#include "pch.h" #include "pch.h"
#include "TraceLogger.h" #include "TraceLogger.h"
#include "NetworkManager.h" #include "NetworkManager.h"
@ -59,7 +57,7 @@ namespace CalculatorApp
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_BEGIN = L"MemoryFlyoutOpenBegin"; constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_BEGIN = L"MemoryFlyoutOpenBegin";
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_END = L"MemoryFlyoutOpenEnd"; constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_END = L"MemoryFlyoutOpenEnd";
constexpr auto EVENT_NAME_MEMORY_CLEAR_ALL = L"MemoryClearAll"; constexpr auto EVENT_NAME_MEMORY_CLEAR_ALL = L"MemoryClearAll";
constexpr auto EVENT_NAME_INVALID_INPUT_PASTED = L"InvalidInputPasted"; constexpr auto EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED = L"InvalidPastedInputOccurred";
constexpr auto EVENT_NAME_VALID_INPUT_PASTED = L"ValidInputPasted"; constexpr auto EVENT_NAME_VALID_INPUT_PASTED = L"ValidInputPasted";
constexpr auto EVENT_NAME_BITFLIP_PANE_CLICKED = L"BitFlipPaneClicked"; constexpr auto EVENT_NAME_BITFLIP_PANE_CLICKED = L"BitFlipPaneClicked";
constexpr auto EVENT_NAME_BITFLIP_BUTTONS_USED = L"BitFlipToggleButtonUsed"; constexpr auto EVENT_NAME_BITFLIP_BUTTONS_USED = L"BitFlipToggleButtonUsed";
@ -81,6 +79,9 @@ namespace CalculatorApp
constexpr auto EVENT_NAME_EXCEPTION = L"Exception"; constexpr auto EVENT_NAME_EXCEPTION = L"Exception";
constexpr auto PDT_PRIVACY_DATA_TAG = L"PartA_PrivTags";
constexpr auto PDT_PRODUCT_AND_SERVICE_USAGE = 0x0000'0000'0200'0000u;
#ifdef SEND_TELEMETRY #ifdef SEND_TELEMETRY
// c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords // c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords
// c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords // c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords
@ -102,7 +103,7 @@ namespace CalculatorApp
g_calculatorProvider( g_calculatorProvider(
L"MicrosoftCalculator", L"MicrosoftCalculator",
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), // Microsoft Telemetry group LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), // Microsoft Telemetry group
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }), //Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0} GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }), // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
m_appLaunchActivity{ nullptr } m_appLaunchActivity{ nullptr }
{ {
// initialize the function array // initialize the function array
@ -176,7 +177,7 @@ namespace CalculatorApp
{ {
iterMap->second.insert(iterMap->second.begin(), L"Programmer"); iterMap->second.insert(iterMap->second.begin(), L"Programmer");
} }
else else if (isStandard)
{ {
iterMap->second.insert(iterMap->second.begin(), L"Standard"); iterMap->second.insert(iterMap->second.begin(), L"Standard");
} }
@ -199,7 +200,7 @@ namespace CalculatorApp
{ {
iterMap->second[memoryPosition] = L"Programmer"; iterMap->second[memoryPosition] = L"Programmer";
} }
else else if (isStandard)
{ {
iterMap->second[memoryPosition] = L"Standard"; iterMap->second[memoryPosition] = L"Standard";
} }
@ -247,7 +248,7 @@ namespace CalculatorApp
{ {
windowIdLog.insert(pair<int, bool>(windowId, false)); windowIdLog.insert(pair<int, bool>(windowId, false));
} }
// if the event is not logged already for the present mode // if the event is not logged already for the present mode
if (currentMode != mode) if (currentMode != mode)
{ {
currentMode = mode; currentMode = mode;
@ -270,7 +271,7 @@ namespace CalculatorApp
{ {
windowIdLog.insert(pair<int, bool>(windowId, false)); windowIdLog.insert(pair<int, bool>(windowId, false));
} }
// if the event is not logged already for the present mode // if the event is not logged already for the present mode
if (currentMode != mode) if (currentMode != mode)
{ {
currentMode = mode; currentMode = mode;
@ -292,7 +293,7 @@ namespace CalculatorApp
{ {
windowIdLog.insert(pair<int, bool>(windowId, false)); windowIdLog.insert(pair<int, bool>(windowId, false));
} }
// if the event is not logged already for the present mode // if the event is not logged already for the present mode
if (currentMode != mode) if (currentMode != mode)
{ {
currentMode = mode; currentMode = mode;
@ -481,9 +482,9 @@ namespace CalculatorApp
LogTelemetryEvent(EVENT_NAME_MEMORY_BODY_OPENED, fields); LogTelemetryEvent(EVENT_NAME_MEMORY_BODY_OPENED, fields);
} }
//If calculator is launched in any mode other than standard then this call will come which is not intended. But there is no way to avoid it. // If calculator is launched in any mode other than standard then this call will come which is not intended. But there is no way to avoid it.
//So don't use this function to analyze the count of mode change in session instead use CalculatorViewedInSession and ConverterViewedInSession to do that. // So don't use this function to analyze the count of mode change in session instead use CalculatorViewedInSession and ConverterViewedInSession to do that.
//Use of this function is to analyze perf of mode change. // Use of this function is to analyze perf of mode change.
void TraceLogger::LogModeChangeBegin(ViewMode fromMode, ViewMode toMode, int windowId) void TraceLogger::LogModeChangeBegin(ViewMode fromMode, ViewMode toMode, int windowId)
{ {
if (!GetTraceLoggingProviderEnabled()) return; if (!GetTraceLoggingProviderEnabled()) return;
@ -498,7 +499,7 @@ namespace CalculatorApp
} }
} }
//comment: same as LogModeChangeBegin // comment: same as LogModeChangeBegin
void TraceLogger::LogModeChangeEnd(ViewMode toMode, int windowId) const void TraceLogger::LogModeChangeEnd(ViewMode toMode, int windowId) const
{ {
if (!GetTraceLoggingProviderEnabled()) return; if (!GetTraceLoggingProviderEnabled()) return;
@ -577,7 +578,7 @@ namespace CalculatorApp
// Writer lock for the static resources // Writer lock for the static resources
reader_writer_lock::scoped_lock lock(s_traceLoggerLock); reader_writer_lock::scoped_lock lock(s_traceLoggerLock);
auto iterMap = s_memoryMap.find(windowId); auto iterMap = s_memoryMap.find(windowId);
LoggingFields fields{}; LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_MEMORY_CLEAR_ALL, fields); LogTelemetryEvent(EVENT_NAME_MEMORY_CLEAR_ALL, fields);
@ -641,17 +642,17 @@ namespace CalculatorApp
LogTelemetryEvent(EVENT_NAME_SINGLE_MEMORY_USED, fields); LogTelemetryEvent(EVENT_NAME_SINGLE_MEMORY_USED, fields);
} }
void TraceLogger::LogInvalidInputPasted(wstring_view reason, wstring_view pastedExpression, ViewMode mode, int programmerNumberBase, int bitLengthType) void TraceLogger::LogInvalidPastedInputOccurred(wstring_view reason, ViewMode mode, int programmerNumberBase, int bitLengthType)
{ {
if (!GetTraceLoggingProviderEnabled()) return; if (!GetTraceLoggingProviderEnabled()) return;
LoggingFields fields{}; LoggingFields fields{};
fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data()); fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"Reason", reason); fields.AddString(L"Reason", reason);
fields.AddString(L"PastedExpression", pastedExpression);
fields.AddString(L"ProgrammerNumberBase", GetProgrammerType(programmerNumberBase).c_str()); fields.AddString(L"ProgrammerNumberBase", GetProgrammerType(programmerNumberBase).c_str());
fields.AddString(L"BitLengthType", GetProgrammerType(bitLengthType).c_str()); fields.AddString(L"BitLengthType", GetProgrammerType(bitLengthType).c_str());
LogTelemetryEvent(EVENT_NAME_INVALID_INPUT_PASTED, fields); fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogTelemetryEvent(EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED, fields);
} }
void TraceLogger::LogValidInputPasted(ViewMode mode) const void TraceLogger::LogValidInputPasted(ViewMode mode) const
@ -872,6 +873,7 @@ namespace CalculatorApp
if (!m_dateDiffUsageLoggedInSession) if (!m_dateDiffUsageLoggedInSession)
{ {
LoggingFields fields{}; LoggingFields fields{};
fields.AddUInt32(L"WindowId", windowId);
LogTelemetryEvent(EVENT_NAME_DATE_DIFFERENCE_USED, fields); LogTelemetryEvent(EVENT_NAME_DATE_DIFFERENCE_USED, fields);
m_dateDiffUsageLoggedInSession = true; m_dateDiffUsageLoggedInSession = true;

View file

@ -9,8 +9,8 @@
static const int maxFunctionSize = (int)CalculationManager::Command::CommandBINEDITEND; static const int maxFunctionSize = (int)CalculationManager::Command::CommandBINEDITEND;
// A trace logging provider can only be instantiated and registered once per module. // A trace logging provider can only be instantiated and registered once per module.
// This class implements a singleton model ensure that only one instance is created. // This class implements a singleton model ensure that only one instance is created.
namespace CalculatorApp namespace CalculatorApp
{ {
struct FuncLog struct FuncLog
@ -64,7 +64,7 @@ namespace CalculatorApp
void LogMemoryFlyoutOpenBegin(unsigned int) const; void LogMemoryFlyoutOpenBegin(unsigned int) const;
void LogDebug(std::wstring_view debugData); void LogDebug(std::wstring_view debugData);
void LogMemoryFlyoutOpenEnd(unsigned int) const; void LogMemoryFlyoutOpenEnd(unsigned int) const;
void LogInvalidInputPasted(std::wstring_view reason, std::wstring_view pastedExpression, CalculatorApp::Common::ViewMode mode, int ProgrammerNumberBase, int bitLengthType); void LogInvalidPastedInputOccurred(std::wstring_view reason, CalculatorApp::Common::ViewMode mode, int ProgrammerNumberBase, int bitLengthType);
void LogValidInputPasted(CalculatorApp::Common::ViewMode mode) const; void LogValidInputPasted(CalculatorApp::Common::ViewMode mode) const;
void UpdateFunctionUsage(int func); void UpdateFunctionUsage(int func);
void LogFunctionUsage(int); void LogFunctionUsage(int);
@ -105,7 +105,7 @@ namespace CalculatorApp
// Any new Log method should // Any new Log method should
// a) decide the level of logging. This will help us in limiting recording of events only up to a certain level. See this link for guidance https://msdn.microsoft.com/en-us/library/windows/desktop/aa363742(v=vs.85).aspx // a) decide the level of logging. This will help us in limiting recording of events only up to a certain level. See this link for guidance https://msdn.microsoft.com/en-us/library/windows/desktop/aa363742(v=vs.85).aspx
// We're using Verbose level for events that are called frequently and needed only for debugging or capturing perf for specific scenarios // We're using Verbose level for events that are called frequently and needed only for debugging or capturing perf for specific scenarios
// b) should decide whether or not to log to telemetry and pass TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY) accordingly // b) should decide whether or not to log to telemetry and pass TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY) accordingly
// c) Should accept a variable number of additional data arguments if needed // c) Should accept a variable number of additional data arguments if needed
void LogTelemetryEvent(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const; void LogTelemetryEvent(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// //
@ -54,7 +54,7 @@ double Utils::GetDoubleFromWstring(wstring input)
return ::atof(inputString.c_str()); return ::atof(inputString.c_str());
} }
//returns windowId for the current view // Returns windowId for the current view
int Utils::GetWindowId() int Utils::GetWindowId()
{ {
int windowId = -1; int windowId = -1;
@ -80,20 +80,13 @@ void Utils::RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Core
} }
} }
// returns if the last character of a wstring is the target wchar_t // Returns if the last character of a wstring is the target wchar_t
bool Utils::IsLastCharacterTarget(_In_ wstring const &input, _In_ wchar_t target) bool Utils::IsLastCharacterTarget(_In_ wstring const &input, _In_ wchar_t target)
{ {
return !input.empty() && input.back() == target; return !input.empty() && input.back() == target;
} }
//return wstring after removing characters like space, comma, and double quotes // Return wstring after removing characters specified by unwantedChars array
wstring Utils::RemoveUnwantedCharsFromWstring(wstring input)
{
wchar_t unWantedChars[] = { L' ', L',', L'"', 8234, 8235, 8236, 8237 };
return RemoveUnwantedCharsFromWstring(input, unWantedChars, 6);
}
//return wstring after removing characters specified by unwantedChars array
wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedChars, unsigned int size) wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedChars, unsigned int size)
{ {
for (unsigned int i = 0; i < size; ++i) for (unsigned int i = 0; i < size; ++i)
@ -110,7 +103,7 @@ void Utils::SerializeCommandsAndTokens(_In_ shared_ptr<CalculatorVector <pair<ws
unsigned int commandsSize; unsigned int commandsSize;
IFTPlatformException(commands->GetSize(&commandsSize)); IFTPlatformException(commands->GetSize(&commandsSize));
// save the size of the commands vector // Save the size of the commands vector
writer->WriteUInt32(commandsSize); writer->WriteUInt32(commandsSize);
SerializeCommandVisitor cmdVisitor(writer); SerializeCommandVisitor cmdVisitor(writer);

View file

@ -54,11 +54,11 @@
#ifndef UNIT_TESTS #ifndef UNIT_TESTS
#define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\ #define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\
internal: void RaisePropertyChanged(Platform::String^ p) {\ internal: void RaisePropertyChanged(Platform::String^ p) {\
PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p)); } public: PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p)); } public:
#else #else
#define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\ #define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\
internal: void RaisePropertyChanged(Platform::String^ p) {\ internal: void RaisePropertyChanged(Platform::String^ p) {\
} public: } public:
#endif #endif
// The callback specified in the macro is a method in the class that will be called every time the object changes // The callback specified in the macro is a method in the class that will be called every time the object changes
@ -68,21 +68,21 @@
internal: void RaisePropertyChanged(Platform::String^ p) {\ internal: void RaisePropertyChanged(Platform::String^ p) {\
PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p));\ PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p));\
c(p);\ c(p);\
} public: } public:
#else #else
#define OBSERVABLE_OBJECT_CALLBACK(c) virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\ #define OBSERVABLE_OBJECT_CALLBACK(c) virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\
internal: void RaisePropertyChanged(Platform::String^ p) {\ internal: void RaisePropertyChanged(Platform::String^ p) {\
c(p);\ c(p);\
} public: } public:
#endif #endif
// The variable member generated by this macro should not be used in the class code, use the // The variable member generated by this macro should not be used in the class code, use the
// property getter instead. // property getter instead.
#define COMMAND_FOR_METHOD(p, m) property Windows::UI::Xaml::Input::ICommand^ p {\ #define COMMAND_FOR_METHOD(p, m) property Windows::UI::Xaml::Input::ICommand^ p {\
Windows::UI::Xaml::Input::ICommand^ get() {\ Windows::UI::Xaml::Input::ICommand^ get() {\
if (!donotuse_##p) {\ if (!donotuse_##p) {\
donotuse_##p = CalculatorApp::Common::MakeDelegate(this, &m);\ donotuse_##p = CalculatorApp::Common::MakeDelegate(this, &m);\
} return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; public: } return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; public:
#define DEPENDENCY_PROPERTY_DECLARATION(t, n)\ #define DEPENDENCY_PROPERTY_DECLARATION(t, n)\
property t n {\ property t n {\
@ -141,7 +141,7 @@ namespace Utils
const wchar_t PDF = 0x202c; // Pop Directional Formatting const wchar_t PDF = 0x202c; // Pop Directional Formatting
const wchar_t LRO = 0x202d; // Left-to-Right Override const wchar_t LRO = 0x202d; // Left-to-Right Override
// Regular DependencyProperty // Regular DependencyProperty
template <typename TOwner, typename TType> template <typename TOwner, typename TType>
Windows::UI::Xaml::DependencyProperty^ RegisterDependencyProperty( Windows::UI::Xaml::DependencyProperty^ RegisterDependencyProperty(
_In_ const wchar_t* const name, _In_ const wchar_t* const name,
@ -205,7 +205,7 @@ namespace Utils
ref new Windows::UI::Xaml::PropertyChangedCallback(callback))); ref new Windows::UI::Xaml::PropertyChangedCallback(callback)));
} }
// Attached DependencyProperty // Attached DependencyProperty
template <typename TOwner, typename TType> template <typename TOwner, typename TType>
Windows::UI::Xaml::DependencyProperty^ RegisterDependencyPropertyAttached( Windows::UI::Xaml::DependencyProperty^ RegisterDependencyPropertyAttached(
_In_ const wchar_t* const name, _In_ const wchar_t* const name,
@ -280,7 +280,6 @@ namespace Utils
Platform::String^ GetStringValue(Platform::String^ input); Platform::String^ GetStringValue(Platform::String^ input);
bool IsLastCharacterTarget(std::wstring const &input, wchar_t target); bool IsLastCharacterTarget(std::wstring const &input, wchar_t target);
std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size); std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size);
std::wstring RemoveUnwantedCharsFromWstring(std::wstring input);
double GetDoubleFromWstring(std::wstring input); double GetDoubleFromWstring(std::wstring input);
int GetWindowId(); int GetWindowId();
void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher^ currentDispatcher); void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher^ currentDispatcher);

View file

@ -14,9 +14,9 @@ namespace CalculatorApp { namespace Common
private: private:
virtual Platform::Object^ Convert( virtual Platform::Object^ Convert(
Platform::Object^ value, Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/, Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{ {
// Pass through as we don't want to change the value from the source // Pass through as we don't want to change the value from the source
@ -24,9 +24,9 @@ namespace CalculatorApp { namespace Common
} }
virtual Platform::Object^ ConvertBack( virtual Platform::Object^ ConvertBack(
Platform::Object^ value, Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/, Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{ {
if (value) if (value)
@ -47,9 +47,9 @@ namespace CalculatorApp { namespace Common
private: private:
virtual Platform::Object^ Convert( virtual Platform::Object^ Convert(
Platform::Object^ value, Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/, Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{ {
// Pass through as we don't want to change the value from the source // Pass through as we don't want to change the value from the source
@ -57,9 +57,9 @@ namespace CalculatorApp { namespace Common
} }
virtual Platform::Object^ ConvertBack( virtual Platform::Object^ ConvertBack(
Platform::Object^ value, Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/, Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{ {
// The value to be valid has to be a boxed int32 value // The value to be valid has to be a boxed int32 value

View file

@ -203,7 +203,7 @@ void CurrencyDataLoader::LoadData()
} }
} }
co_return didLoad; co_return didLoad;
}).then([this](bool didLoad) }).then([this](bool didLoad)
{ {
UpdateDisplayedTimestamp(); UpdateDisplayedTimestamp();
@ -275,7 +275,7 @@ pair<wstring, wstring> CurrencyDataLoader::GetCurrencyRatioEquality(_In_ const U
{ {
double ratio = (iter2->second).ratio; double ratio = (iter2->second).ratio;
// Round the raio to FORMATTER_DIGIT_COUNT digits using int math. // Round the ratio to FORMATTER_DIGIT_COUNT digits using int math.
// Ex: to round 1.23456 to three digits, use // Ex: to round 1.23456 to three digits, use
// ((int) 1.23456 * (10^3)) / (10^3) // ((int) 1.23456 * (10^3)) / (10^3)
double scale = pow(10, FORMATTER_DIGIT_COUNT); double scale = pow(10, FORMATTER_DIGIT_COUNT);
@ -329,7 +329,7 @@ task<bool> CurrencyDataLoader::TryLoadDataFromCacheAsync()
{ {
loadComplete = co_await TryLoadDataFromWebAsync(); loadComplete = co_await TryLoadDataFromWebAsync();
} }
if (!loadComplete) if (!loadComplete)
{ {
loadComplete = co_await TryFinishLoadFromCacheAsync(); loadComplete = co_await TryFinishLoadFromCacheAsync();

View file

@ -87,7 +87,7 @@ namespace CalculatorApp
bool TryParseWebResponses( bool TryParseWebResponses(
_In_ Platform::String^ staticDataJson, _In_ Platform::String^ staticDataJson,
_In_ Platform::String^ allRatiosJson, _In_ Platform::String^ allRatiosJson,
_Inout_ std::vector<UCM::CurrencyStaticData>& staticData, _Inout_ std::vector<UCM::CurrencyStaticData>& staticData,
_Inout_ CurrencyRatioMap& allRatiosData); _Inout_ CurrencyRatioMap& allRatiosData);
bool TryParseStaticData(_In_ Platform::String^ rawJson, _Inout_ std::vector<UCM::CurrencyStaticData>& staticData); bool TryParseStaticData(_In_ Platform::String^ rawJson, _Inout_ std::vector<UCM::CurrencyStaticData>& staticData);

View file

@ -200,7 +200,7 @@ void UnitConverterDataLoader::GetUnits(_In_ unordered_map<ViewMode, vector<Order
dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Exbibits, GetLocalizedStringName(L"UnitName_Exbibits"), GetLocalizedStringName(L"UnitAbbreviation_Exbibits"), 24 }); dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Exbibits, GetLocalizedStringName(L"UnitName_Exbibits"), GetLocalizedStringName(L"UnitAbbreviation_Exbibits"), 24 });
dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Exbibytes, GetLocalizedStringName(L"UnitName_Exbibytes"), GetLocalizedStringName(L"UnitAbbreviation_Exbibytes"), 26 }); dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Exbibytes, GetLocalizedStringName(L"UnitName_Exbibytes"), GetLocalizedStringName(L"UnitAbbreviation_Exbibytes"), 26 });
dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gibibits, GetLocalizedStringName(L"UnitName_Gibibits"), GetLocalizedStringName(L"UnitAbbreviation_Gibibits"), 12 }); dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gibibits, GetLocalizedStringName(L"UnitName_Gibibits"), GetLocalizedStringName(L"UnitAbbreviation_Gibibits"), 12 });
dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gibibytes, GetLocalizedStringName(L"UnitName_Gibibytes"), GetLocalizedStringName(L"UnitAbbreviation_Gibibytes"), 14 }); dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gibibytes, GetLocalizedStringName(L"UnitName_Gibibytes"), GetLocalizedStringName(L"UnitAbbreviation_Gibibytes"), 14 });
dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gigabit, GetLocalizedStringName(L"UnitName_Gigabit"), GetLocalizedStringName(L"UnitAbbreviation_Gigabit"), 11 }); dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gigabit, GetLocalizedStringName(L"UnitName_Gigabit"), GetLocalizedStringName(L"UnitAbbreviation_Gigabit"), 11 });
dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gigabyte, GetLocalizedStringName(L"UnitName_Gigabyte"), GetLocalizedStringName(L"UnitAbbreviation_Gigabyte"),13, true, false, false}); dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Gigabyte, GetLocalizedStringName(L"UnitName_Gigabyte"), GetLocalizedStringName(L"UnitAbbreviation_Gigabyte"),13, true, false, false});
dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Kibibits, GetLocalizedStringName(L"UnitName_Kibibits"), GetLocalizedStringName(L"UnitAbbreviation_Kibibits"), 4 }); dataUnits.push_back(OrderedUnit{ UnitConverterUnits::Data_Kibibits, GetLocalizedStringName(L"UnitName_Kibibits"), GetLocalizedStringName(L"UnitAbbreviation_Kibibits"), 4 });

View file

@ -73,7 +73,7 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
// Initialize the list separator delimiter appended with a space at the end, e.g. ", " // Initialize the list separator delimiter appended with a space at the end, e.g. ", "
// This will be used for date difference formatting: Y years, M months, W weeks, D days // This will be used for date difference formatting: Y years, M months, W weeks, D days
m_listSeparator = ref new String((localizationSettings.GetListSeparator() + L" ").c_str()); m_listSeparator = localizationSettings.GetListSeparator() + L" ";
// Initialize the output results // Initialize the output results
UpdateDisplayResult(); UpdateDisplayResult();
@ -180,9 +180,9 @@ void DateCalculatorViewModel::UpdateDisplayResult()
StrDateDiffResultInDays = L""; StrDateDiffResultInDays = L"";
StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates"); StrDateDiffResult = AppResourceProvider::GetInstance().GetResourceString(L"Date_SameDates");
} }
else if ((m_dateDiffResult.year == 0) && else if ((m_dateDiffResult.year == 0) &&
(m_dateDiffResult.month == 0) && (m_dateDiffResult.month == 0) &&
(m_dateDiffResult.week == 0)) (m_dateDiffResult.week == 0))
{ {
IsDiffInDays = true; IsDiffInDays = true;
StrDateDiffResultInDays = L""; StrDateDiffResultInDays = L"";
@ -245,22 +245,23 @@ void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String^ calendarI
String^ DateCalculatorViewModel::GetDateDiffString() const String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
String^ result = L""; wstring result;
bool addDelimiter = false; bool addDelimiter = false;
AppResourceProvider resourceLoader = AppResourceProvider::GetInstance(); AppResourceProvider resourceLoader = AppResourceProvider::GetInstance();
auto yearCount = m_dateDiffResult.year; auto yearCount = m_dateDiffResult.year;
if (yearCount > 0) if (yearCount > 0)
{ {
result = String::Concat(GetLocalizedNumberString(yearCount), L" "); result += GetLocalizedNumberString(yearCount)->Data();
result += L" ";
if (yearCount > 1) if (yearCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Years")); result += resourceLoader.GetResourceString(L"Date_Years")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Year")); result += resourceLoader.GetResourceString(L"Date_Year")->Data();
} }
// set the flags to add a delimiter whenever the next unit is added // set the flags to add a delimiter whenever the next unit is added
@ -272,22 +273,23 @@ String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
if (addDelimiter) if (addDelimiter)
{ {
result = String::Concat(result, m_listSeparator); result += m_listSeparator;
} }
else else
{ {
addDelimiter = true; addDelimiter = true;
} }
result = String::Concat(result, String::Concat(GetLocalizedNumberString(monthCount), L" ")); result += GetLocalizedNumberString(monthCount)->Data();
result += L" ";
if (monthCount > 1) if (monthCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Months")); result += resourceLoader.GetResourceString(L"Date_Months")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Month")); result += resourceLoader.GetResourceString(L"Date_Month")->Data();
} }
} }
@ -296,22 +298,23 @@ String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
if (addDelimiter) if (addDelimiter)
{ {
result = String::Concat(result, m_listSeparator); result += m_listSeparator;
} }
else else
{ {
addDelimiter = true; addDelimiter = true;
} }
result = String::Concat(result, String::Concat(GetLocalizedNumberString(weekCount), L" ")); result += GetLocalizedNumberString(weekCount)->Data();
result += L" ";
if (weekCount > 1) if (weekCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Weeks")); result += resourceLoader.GetResourceString(L"Date_Weeks")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Week")); result += resourceLoader.GetResourceString(L"Date_Week")->Data();
} }
} }
@ -320,43 +323,45 @@ String^ DateCalculatorViewModel::GetDateDiffString() const
{ {
if (addDelimiter) if (addDelimiter)
{ {
result = String::Concat(result, m_listSeparator); result += m_listSeparator;
} }
else else
{ {
addDelimiter = true; addDelimiter = true;
} }
result = String::Concat(result, String::Concat(GetLocalizedNumberString(dayCount), L" ")); result += GetLocalizedNumberString(dayCount)->Data();
result += L" ";
if (dayCount > 1) if (dayCount > 1)
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Days")); result += resourceLoader.GetResourceString(L"Date_Days")->Data();
} }
else else
{ {
result = String::Concat(result, resourceLoader.GetResourceString(L"Date_Day")); result += resourceLoader.GetResourceString(L"Date_Day")->Data();
} }
} }
return result; return ref new String(result.data());
} }
String^ DateCalculatorViewModel::GetDateDiffStringInDays() const String^ DateCalculatorViewModel::GetDateDiffStringInDays() const
{ {
String^ strDateUnit; wstring result = GetLocalizedNumberString(m_dateDiffResultInDays.day)->Data();
result += L" ";
// Display the result as '1 day' or 'N days' // Display the result as '1 day' or 'N days'
if (m_dateDiffResultInDays.day > 1) if (m_dateDiffResultInDays.day > 1)
{ {
strDateUnit = AppResourceProvider::GetInstance().GetResourceString(L"Date_Days"); result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Days")->Data();
} }
else else
{ {
strDateUnit = AppResourceProvider::GetInstance().GetResourceString(L"Date_Day"); result += AppResourceProvider::GetInstance().GetResourceString(L"Date_Day")->Data();
} }
return String::Concat(GetLocalizedNumberString(m_dateDiffResultInDays.day), String::Concat(L" ", strDateUnit)); return ref new String(result.data());
} }
void DateCalculatorViewModel::OnCopyCommand(Platform::Object^ parameter) void DateCalculatorViewModel::OnCopyCommand(Platform::Object^ parameter)

View file

@ -146,7 +146,7 @@ namespace CalculatorApp
CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat;
CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter^ m_dateTimeFormatter; Windows::Globalization::DateTimeFormatting::DateTimeFormatter^ m_dateTimeFormatter;
Platform::String^ m_listSeparator; std::wstring m_listSeparator;
}; };
} }
} }

View file

@ -17,18 +17,18 @@ namespace CalculatorApp
internal: internal:
HistoryItemViewModel(Platform::String^ expression, HistoryItemViewModel(Platform::String^ expression,
Platform::String^ result, Platform::String^ result,
_In_ std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> const &spTokens, _In_ std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> const &spTokens,
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &spCommands); _In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &spCommands);
std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> const& GetTokens() std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> const& GetTokens()
{ {
return m_spTokens; return m_spTokens;
} }
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& GetCommands() std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& GetCommands()
{ {
return m_spCommands; return m_spCommands;
} }
public: public:

View file

@ -64,7 +64,7 @@ void HistoryViewModel::ReloadHistory(_In_ ViewMode currentMode)
if (historyListModel.size() > 0) if (historyListModel.size() > 0)
{ {
for (auto ritr = historyListModel.rbegin(); ritr != historyListModel.rend(); ++ritr) for (auto ritr = historyListModel.rbegin(); ritr != historyListModel.rend(); ++ritr)
{ {
wstring expression = (*ritr)->historyItemVector.expression; wstring expression = (*ritr)->historyItemVector.expression;
wstring result = (*ritr)->historyItemVector.result; wstring result = (*ritr)->historyItemVector.result;
localizer.LocalizeDisplayValue(&expression); localizer.LocalizeDisplayValue(&expression);
@ -291,7 +291,6 @@ void HistoryViewModel::SaveHistory()
// this serializes a history item into a base64 encoded string // this serializes a history item into a base64 encoded string
Platform::String^ HistoryViewModel::SerializeHistoryItem(_In_ std::shared_ptr<CalculationManager::HISTORYITEM> const &item) Platform::String^ HistoryViewModel::SerializeHistoryItem(_In_ std::shared_ptr<CalculationManager::HISTORYITEM> const &item)
{ {
HRESULT hr = S_OK;
DataWriter^ writer = ref new DataWriter(); DataWriter^ writer = ref new DataWriter();
auto expr = item->historyItemVector.expression; auto expr = item->historyItemVector.expression;
auto result = item->historyItemVector.result; auto result = item->historyItemVector.result;

View file

@ -41,8 +41,9 @@ namespace CalculatorApp::ViewModel
StringReference DisplayValue(L"DisplayValue"); StringReference DisplayValue(L"DisplayValue");
StringReference IsInError(L"IsInError"); StringReference IsInError(L"IsInError");
StringReference BinaryDisplayValue(L"BinaryDisplayValue"); StringReference BinaryDisplayValue(L"BinaryDisplayValue");
StringReference OpenParenthesisCount(L"OpenParenthesisCount");
} }
namespace CalculatorResourceKeys namespace CalculatorResourceKeys
{ {
StringReference CalculatorExpression(L"Format_CalculatorExpression"); StringReference CalculatorExpression(L"Format_CalculatorExpression");
@ -53,6 +54,8 @@ namespace CalculatorApp::ViewModel
StringReference OctButton(L"Format_OctButtonValue"); StringReference OctButton(L"Format_OctButtonValue");
StringReference BinButton(L"Format_BinButtonValue"); StringReference BinButton(L"Format_BinButtonValue");
StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix"); StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix");
StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix");
StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement");
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback"); StringReference ButtonPressFeedbackFormat(L"Format_ButtonPressAuditoryFeedback");
StringReference MemorySave(L"Format_MemorySave"); StringReference MemorySave(L"Format_MemorySave");
@ -92,7 +95,9 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_localizedMemorySavedAutomationFormat(nullptr), m_localizedMemorySavedAutomationFormat(nullptr),
m_localizedMemoryItemChangedAutomationFormat(nullptr), m_localizedMemoryItemChangedAutomationFormat(nullptr),
m_localizedMemoryItemClearedAutomationFormat(nullptr), m_localizedMemoryItemClearedAutomationFormat(nullptr),
m_localizedMemoryCleared(nullptr) m_localizedMemoryCleared(nullptr),
m_localizedOpenParenthesisCountChangedAutomationFormat(nullptr),
m_localizedNoRightParenthesisAddedFormat(nullptr)
{ {
WeakReference calculatorViewModel(this); WeakReference calculatorViewModel(this);
m_calculatorDisplay.SetCallback(calculatorViewModel); m_calculatorDisplay.SetCallback(calculatorViewModel);
@ -178,7 +183,6 @@ String^ StandardCalculatorViewModel::CalculateNarratorDisplayValue(_In_ wstring
String^ StandardCalculatorViewModel::GetNarratorStringReadRawNumbers(_In_ String^ localizedDisplayValue) String^ StandardCalculatorViewModel::GetNarratorStringReadRawNumbers(_In_ String^ localizedDisplayValue)
{ {
wstringstream wss; wstringstream wss;
RADIX_TYPE radix = static_cast<RADIX_TYPE>(CurrentRadixType);
auto& locSettings = LocalizationSettings::GetInstance(); auto& locSettings = LocalizationSettings::GetInstance();
// Insert a space after each digit in the string, to force Narrator to read them as separate numbers. // Insert a space after each digit in the string, to force Narrator to read them as separate numbers.
@ -227,6 +231,34 @@ void StandardCalculatorViewModel::SetParenthesisCount(_In_ const wstring& parent
} }
} }
void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement()
{
String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount);
wstring localizedParenthesisCount = parenthesisCount->Data();
LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
CalculatorResourceKeys::OpenParenthesisCountAutomationFormat,
m_localizedOpenParenthesisCountChangedAutomationFormat,
localizedParenthesisCount.c_str());
Announcement = CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(announcement);
}
void StandardCalculatorViewModel::OnNoRightParenAdded()
{
SetNoParenAddedNarratorAnnouncement();
}
void StandardCalculatorViewModel::SetNoParenAddedNarratorAnnouncement()
{
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
CalculatorResourceKeys::NoParenthesisAdded,
m_localizedNoRightParenthesisAddedFormat);
Announcement = CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(announcement);
}
void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType) void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionCommandType)
{ {
if (selectedExpressionCommandType == CommandType::OperandCommand) if (selectedExpressionCommandType == CommandType::OperandCommand)
@ -426,50 +458,50 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
displayExpressionToken->CommandIndex = 0; displayExpressionToken->CommandIndex = 0;
} }
wchar_t ch; wchar_t ch = 0;
if ((cmdenum >= Command::Command0) && (cmdenum <= Command::Command9)) if ((cmdenum >= Command::Command0) && (cmdenum <= Command::Command9))
{ {
switch (cmdenum) switch (cmdenum)
{ {
case Command::Command0: case Command::Command0:
ch = '0'; ch = L'0';
break; break;
case Command::Command1: case Command::Command1:
ch = '1'; ch = L'1';
break; break;
case Command::Command2: case Command::Command2:
ch = '2'; ch = L'2';
break; break;
case Command::Command3: case Command::Command3:
ch = '3'; ch = L'3';
break; break;
case Command::Command4: case Command::Command4:
ch = '4'; ch = L'4';
break; break;
case Command::Command5: case Command::Command5:
ch = '5'; ch = L'5';
break; break;
case Command::Command6: case Command::Command6:
ch = '6'; ch = L'6';
break; break;
case Command::Command7: case Command::Command7:
ch = '7'; ch = L'7';
break; break;
case Command::Command8: case Command::Command8:
ch = '8'; ch = L'8';
break; break;
case Command::Command9: case Command::Command9:
ch = '9'; ch = L'9';
break; break;
} }
} }
else if (cmdenum == Command::CommandPNT) else if (cmdenum == Command::CommandPNT)
{ {
ch = '.'; ch = L'.';
} }
else if (cmdenum == Command::CommandBACK) else if (cmdenum == Command::CommandBACK)
{ {
ch = 'x'; ch = L'x';
} }
else else
{ {
@ -484,9 +516,9 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
if (IsOperandTextCompletelySelected) if (IsOperandTextCompletelySelected)
{ {
//Clear older text; // Clear older text;
m_selectedExpressionLastData = L""; m_selectedExpressionLastData = L"";
if (ch == 'x') if (ch == L'x')
{ {
temp[0] = L'\0'; temp[0] = L'\0';
commandIndex = 0; commandIndex = 0;
@ -501,7 +533,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
} }
else else
{ {
if (ch == 'x') if (ch == L'x')
{ {
if (commandIndex == 0) if (commandIndex == 0)
{ {
@ -518,7 +550,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
} }
temp[i++] = data[j]; temp[i++] = data[j];
} }
temp[i] = '\0'; temp[i] = L'\0';
commandIndex -= 1; commandIndex -= 1;
} }
else else
@ -526,6 +558,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
length = m_selectedExpressionLastData->Length() + 1; length = m_selectedExpressionLastData->Length() + 1;
if (length > 50) if (length > 50)
{ {
delete [] temp;
return; return;
} }
for (; i < length; ++i) for (; i < length; ++i)
@ -537,7 +570,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
} }
temp[i] = data[j++]; temp[i] = data[j++];
} }
temp[i] = '\0'; temp[i] = L'\0';
commandIndex += 1; commandIndex += 1;
} }
} }
@ -567,14 +600,13 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter)
m_feedbackForButtonPress = CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParameter(parameter); m_feedbackForButtonPress = CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParameter(parameter);
NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter); NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter);
Command cmdenum = ConvertToOperatorsEnum(numOpEnum); Command cmdenum = ConvertToOperatorsEnum(numOpEnum);
bool isOperator = IsOperator(cmdenum);
TraceLogger::GetInstance().UpdateFunctionUsage((int)numOpEnum); TraceLogger::GetInstance().UpdateFunctionUsage((int)numOpEnum);
if (IsInError) if (IsInError)
{ {
m_standardCalculatorManager.SendCommand(Command::CommandCLEAR); m_standardCalculatorManager.SendCommand(Command::CommandCLEAR);
if (!IsRecoverableCommand((int)numOpEnum)) if (!IsRecoverableCommand((int)numOpEnum))
{ {
return; return;
@ -748,7 +780,6 @@ void StandardCalculatorViewModel::OnPaste(String^ pastedString, ViewMode mode)
bool isFirstLegalChar = true; bool isFirstLegalChar = true;
m_standardCalculatorManager.SendCommand(Command::CommandCENTR); m_standardCalculatorManager.SendCommand(Command::CommandCENTR);
bool sendNegate = false; bool sendNegate = false;
bool processedExp = false;
bool processedDigit = false; bool processedDigit = false;
bool sentEquals = false; bool sentEquals = false;
bool isPreviousOperator = false; bool isPreviousOperator = false;
@ -838,8 +869,8 @@ void StandardCalculatorViewModel::OnPaste(String^ pastedString, ViewMode mode)
Command cmdenum = ConvertToOperatorsEnum(mappedNumOp); Command cmdenum = ConvertToOperatorsEnum(mappedNumOp);
m_standardCalculatorManager.SendCommand(cmdenum); m_standardCalculatorManager.SendCommand(cmdenum);
// The CalcEngine state machine won't allow the negate command to be sent before any // The CalcEngine state machine won't allow the negate command to be sent before any
// other digits, so instead a flag is set and the command is sent after the first appropriate // other digits, so instead a flag is set and the command is sent after the first appropriate
// command. // command.
if (sendNegate) if (sendNegate)
{ {
@ -1165,10 +1196,10 @@ Array<unsigned char>^ StandardCalculatorViewModel::Serialize()
writer->WriteInt32(data); writer->WriteInt32(data);
} }
//For ProgrammerMode // For ProgrammerMode
writer->WriteUInt32(static_cast<UINT32>(CurrentRadixType)); writer->WriteUInt32(static_cast<UINT32>(CurrentRadixType));
//Serialize commands of calculator manager // Serialize commands of calculator manager
vector<unsigned char> serializedCommand = m_standardCalculatorManager.SerializeCommands(); vector<unsigned char> serializedCommand = m_standardCalculatorManager.SerializeCommands();
writer->WriteUInt32(static_cast<UINT32>(serializedCommand.size())); writer->WriteUInt32(static_cast<UINT32>(serializedCommand.size()));
writer->WriteBytes(ref new Array<unsigned char>(serializedCommand.data(), static_cast<unsigned int>(serializedCommand.size()))); writer->WriteBytes(ref new Array<unsigned char>(serializedCommand.data(), static_cast<unsigned int>(serializedCommand.size())));
@ -1178,7 +1209,7 @@ Array<unsigned char>^ StandardCalculatorViewModel::Serialize()
Utils::SerializeCommandsAndTokens(m_tokens, m_commands, writer); Utils::SerializeCommandsAndTokens(m_tokens, m_commands, writer);
} }
//Convert viewmodel data in writer to bytes // Convert viewmodel data in writer to bytes
IBuffer^ buffer = writer->DetachBuffer(); IBuffer^ buffer = writer->DetachBuffer();
DataReader^ reader = DataReader::FromBuffer(buffer); DataReader^ reader = DataReader::FromBuffer(buffer);
Platform::Array<unsigned char>^ viewModelDataAsBytes = ref new Array<unsigned char>(buffer->Length); Platform::Array<unsigned char>^ viewModelDataAsBytes = ref new Array<unsigned char>(buffer->Length);
@ -1226,7 +1257,7 @@ void StandardCalculatorViewModel::Deserialize(Array<unsigned char>^ state)
m_standardCalculatorManager.DeSerializePrimaryDisplay(serializedPrimaryDisplay); m_standardCalculatorManager.DeSerializePrimaryDisplay(serializedPrimaryDisplay);
CurrentRadixType = reader->ReadUInt32(); CurrentRadixType = reader->ReadUInt32();
//Read command data and Deserialize // Read command data and Deserialize
UINT32 modeldatalength = reader->ReadUInt32(); UINT32 modeldatalength = reader->ReadUInt32();
Array<unsigned char>^ modelDataAsBytes = ref new Array<unsigned char>(modeldatalength); Array<unsigned char>^ modelDataAsBytes = ref new Array<unsigned char>(modeldatalength);
reader->ReadBytes(modelDataAsBytes); reader->ReadBytes(modelDataAsBytes);
@ -1371,7 +1402,6 @@ ANGLE_TYPE GetAngleTypeFromCommand(Command command)
void StandardCalculatorViewModel::SaveEditedCommand(_In_ unsigned int tokenPosition, _In_ Command command) void StandardCalculatorViewModel::SaveEditedCommand(_In_ unsigned int tokenPosition, _In_ Command command)
{ {
pair<wstring, int> token; pair<wstring, int> token;
bool fNegative = false;
bool handleOperand = false; bool handleOperand = false;
int nOpCode = static_cast<int>(command); int nOpCode = static_cast<int>(command);
wstring updatedToken = L""; wstring updatedToken = L"";
@ -1574,7 +1604,7 @@ void StandardCalculatorViewModel::Recalculate(bool fromHistory)
m_standardCalculatorManager.SendCommand(static_cast<CalculationManager::Command>(currentCommands[i])); m_standardCalculatorManager.SendCommand(static_cast<CalculationManager::Command>(currentCommands[i]));
} }
if (fromHistory) // This is for the cases where the expression is loaded from history if (fromHistory) // This is for the cases where the expression is loaded from history
{ {
// To maintain F-E state of the engine, as the last operand hasn't reached engine by now // To maintain F-E state of the engine, as the last operand hasn't reached engine by now
m_standardCalculatorManager.SendCommand(Command::CommandFE); m_standardCalculatorManager.SendCommand(Command::CommandFE);
@ -1618,7 +1648,7 @@ bool StandardCalculatorViewModel::IsOpnd(int nOpCode)
Command::CommandPNT Command::CommandPNT
}; };
for (int i = 0; i < ARRAYSIZE(opnd); i++) for (unsigned int i = 0; i < size(opnd); i++)
{ {
if (nOpCode == static_cast<int>(opnd[i])) if (nOpCode == static_cast<int>(opnd[i]))
{ {
@ -1649,7 +1679,7 @@ bool StandardCalculatorViewModel::IsUnaryOp(int nOpCode)
Command::CommandCUB Command::CommandCUB
}; };
for (int i = 0; i < ARRAYSIZE(unaryOp); i++) for (unsigned int i = 0; i < size(unaryOp); i++)
{ {
if (nOpCode == static_cast<int>(unaryOp[i])) if (nOpCode == static_cast<int>(unaryOp[i]))
{ {
@ -1676,7 +1706,7 @@ bool StandardCalculatorViewModel::IsTrigOp(int nOpCode)
Command::CommandATAN Command::CommandATAN
}; };
for (int i = 0; i < ARRAYSIZE(trigOp); i++) for (unsigned int i = 0; i < size(trigOp); i++)
{ {
if (nOpCode == static_cast<int>(trigOp[i])) if (nOpCode == static_cast<int>(trigOp[i]))
{ {
@ -1699,7 +1729,7 @@ bool StandardCalculatorViewModel::IsBinOp(int nOpCode)
Command::CommandPWR Command::CommandPWR
}; };
for (int i = 0; i < ARRAYSIZE(binOp); i++) for (unsigned int i = 0; i < size(binOp); i++)
{ {
if (nOpCode == static_cast<int>(binOp[i])) if (nOpCode == static_cast<int>(binOp[i]))
{ {
@ -1733,7 +1763,7 @@ bool StandardCalculatorViewModel::IsRecoverableCommand(int nOpCode)
Command::CommandF Command::CommandF
}; };
for (int i = 0; i < ARRAYSIZE(recoverableCommands); i++) for (unsigned int i = 0; i < size(recoverableCommands); i++)
{ {
if (nOpCode == static_cast<int>(recoverableCommands[i])) if (nOpCode == static_cast<int>(recoverableCommands[i]))
{ {
@ -1951,7 +1981,7 @@ void StandardCalculatorViewModel::UpdatecommandsInRecordingMode()
} }
else else
{ {
//reset all vars // Reset all vars
isDecimal = false; isDecimal = false;
isNegative = false; isNegative = false;
isExpMode = false; isExpMode = false;

View file

@ -36,6 +36,7 @@ namespace CalculatorApp
extern Platform::StringReference IsMemoryEmpty; extern Platform::StringReference IsMemoryEmpty;
extern Platform::StringReference IsInError; extern Platform::StringReference IsInError;
extern Platform::StringReference BinaryDisplayValue; extern Platform::StringReference BinaryDisplayValue;
extern Platform::StringReference OpenParenthesisCount;
} }
[Windows::UI::Xaml::Data::Bindable] [Windows::UI::Xaml::Data::Bindable]
@ -263,7 +264,7 @@ namespace CalculatorApp
property Platform::String^ LeftParenthesisAutomationName property Platform::String^ LeftParenthesisAutomationName
{ {
Platform::String^ get() Platform::String^ get()
{ {
return GetLeftParenthesisAutomationName(); return GetLeftParenthesisAutomationName();
} }
@ -276,7 +277,7 @@ namespace CalculatorApp
NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate); NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate);
//Memory feature related methods. They are internal because they need to called from the MainPage code-behind // Memory feature related methods. They are internal because they need to called from the MainPage code-behind
void OnMemoryButtonPressed(); void OnMemoryButtonPressed();
void OnMemoryItemPressed(Platform::Object^ memoryItemPosition); void OnMemoryItemPressed(Platform::Object^ memoryItemPosition);
void OnMemoryAdd(Platform::Object^ memoryItemPosition); void OnMemoryAdd(Platform::Object^ memoryItemPosition);
@ -290,6 +291,9 @@ namespace CalculatorApp
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands); void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands);
void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands); void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands);
void SetParenthesisCount(_In_ const std::wstring& parenthesisCount); void SetParenthesisCount(_In_ const std::wstring& parenthesisCount);
void SetOpenParenthesisCountNarratorAnnouncement();
void OnNoRightParenAdded();
void SetNoParenAddedNarratorAnnouncement();
void OnMaxDigitsReached(); void OnMaxDigitsReached();
void OnBinaryOperatorReceived(); void OnBinaryOperatorReceived();
void OnMemoryItemChanged(unsigned int indexOfMemory); void OnMemoryItemChanged(unsigned int indexOfMemory);
@ -337,6 +341,8 @@ namespace CalculatorApp
Platform::String^ m_localizedMemoryItemChangedAutomationFormat; Platform::String^ m_localizedMemoryItemChangedAutomationFormat;
Platform::String^ m_localizedMemoryItemClearedAutomationFormat; Platform::String^ m_localizedMemoryItemClearedAutomationFormat;
Platform::String^ m_localizedMemoryCleared; Platform::String^ m_localizedMemoryCleared;
Platform::String^ m_localizedOpenParenthesisCountChangedAutomationFormat;
Platform::String^ m_localizedNoRightParenthesisAddedFormat;
bool m_pinned; bool m_pinned;
bool m_isOperandEnabled; bool m_isOperandEnabled;

View file

@ -142,7 +142,7 @@ UnitConverterViewModel::UnitConverterViewModel(const shared_ptr<UCM::IUnitConver
m_currencyFormatter->Mode = CurrencyFormatterMode::UseCurrencyCode; m_currencyFormatter->Mode = CurrencyFormatterMode::UseCurrencyCode;
m_currencyFormatter->ApplyRoundingForCurrency(RoundingAlgorithm::RoundHalfDown); m_currencyFormatter->ApplyRoundingForCurrency(RoundingAlgorithm::RoundHalfDown);
m_currencyMaxFractionDigits = m_currencyFormatter->FractionDigits; m_currencyMaxFractionDigits = m_currencyFormatter->FractionDigits;
auto resourceLoader = AppResourceProvider::GetInstance(); auto resourceLoader = AppResourceProvider::GetInstance();
m_localizedValueFromFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromFormat); m_localizedValueFromFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueFromFormat);
m_localizedValueToFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueToFormat); m_localizedValueToFormat = resourceLoader.GetResourceString(UnitConverterResourceKeys::ValueToFormat);
@ -257,7 +257,7 @@ void UnitConverterViewModel::OnUnitChanged(Object^ parameter)
void UnitConverterViewModel::OnSwitchActive(Platform::Object^ unused) void UnitConverterViewModel::OnSwitchActive(Platform::Object^ unused)
{ {
// this can be false if this switch occurs without the user having explicitly updated any strings // this can be false if this switch occurs without the user having explicitly updated any strings
// (for example, during deserialization). We only want to try this cleanup if there's actually // (for example, during deserialization). We only want to try this cleanup if there's actually
// something to clean up. // something to clean up.
if (m_relocalizeStringOnSwitch) if (m_relocalizeStringOnSwitch)
@ -279,7 +279,7 @@ void UnitConverterViewModel::OnSwitchActive(Platform::Object^ unused)
m_valueFromUnlocalized.swap(m_valueToUnlocalized); m_valueFromUnlocalized.swap(m_valueToUnlocalized);
Utils::Swap(&m_localizedValueFromFormat, &m_localizedValueToFormat); Utils::Swap(&m_localizedValueFromFormat, &m_localizedValueToFormat);
Utils::Swap(&m_Unit1AutomationName, &m_Unit2AutomationName); Utils::Swap(&m_Unit1AutomationName, &m_Unit2AutomationName);
RaisePropertyChanged(UnitConverterViewModelProperties::Unit1AutomationName); RaisePropertyChanged(UnitConverterViewModelProperties::Unit1AutomationName);
RaisePropertyChanged(UnitConverterViewModelProperties::Unit2AutomationName); RaisePropertyChanged(UnitConverterViewModelProperties::Unit2AutomationName);
@ -324,7 +324,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
if (allowPartialStrings) if (allowPartialStrings)
{ {
// allow "in progress" strings, like "3." that occur during the composition of // allow "in progress" strings, like "3." that occur during the composition of
// a final number. Without this, when typing the three characters in "3.2" // a final number. Without this, when typing the three characters in "3.2"
// you don't see the decimal point when typing it, you only see it once you've finally // you don't see the decimal point when typing it, you only see it once you've finally
// typed a post-decimal digit. // typed a post-decimal digit.
@ -341,7 +341,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
{ {
wstring currencyResult = m_currencyFormatter->Format(stod(stringToLocalize))->Data(); wstring currencyResult = m_currencyFormatter->Format(stod(stringToLocalize))->Data();
wstring currencyCode = m_currencyFormatter->Currency->Data(); wstring currencyCode = m_currencyFormatter->Currency->Data();
// CurrencyFormatter always includes LangCode or Symbol. Make it include LangCode // CurrencyFormatter always includes LangCode or Symbol. Make it include LangCode
// because this includes a non-breaking space. Remove the LangCode. // because this includes a non-breaking space. Remove the LangCode.
auto pos = currencyResult.find(currencyCode); auto pos = currencyResult.find(currencyCode);
@ -367,7 +367,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
if (hasDecimal) if (hasDecimal)
{ {
// Since the output from GetLocaleInfoEx() and DecimalFormatter are differing for decimal string // Since the output from GetLocaleInfoEx() and DecimalFormatter are differing for decimal string
// we are adding the below work-around of editing the string returned by DecimalFormatter // we are adding the below work-around of editing the string returned by DecimalFormatter
// and replacing the decimal separator with the one returned by GetLocaleInfoEx() // and replacing the decimal separator with the one returned by GetLocaleInfoEx()
String^ formattedSampleString = m_decimalFormatter->Format(stod("1.1")); String^ formattedSampleString = m_decimalFormatter->Format(stod("1.1"));
wstring formattedSampleWString = wstring(formattedSampleString->Data()); wstring formattedSampleWString = wstring(formattedSampleString->Data());
@ -378,7 +378,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
{ {
resultWithDecimal.replace(pos, 1, &m_decimalSeparator); resultWithDecimal.replace(pos, 1, &m_decimalSeparator);
} }
// Copy back the edited string to the result // Copy back the edited string to the result
result = ref new String(resultWithDecimal.c_str()); result = ref new String(resultWithDecimal.c_str());
} }
@ -479,7 +479,7 @@ void UnitConverterViewModel::OnButtonPressed(Platform::Object^ parameter)
NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter); NumbersAndOperatorsEnum numOpEnum = CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(parameter);
UCM::Command command = CommandFromButtonId(numOpEnum); UCM::Command command = CommandFromButtonId(numOpEnum);
//Don't clear the display if combo box is open and escape is pressed // Don't clear the display if combo box is open and escape is pressed
if (command == UCM::Command::Clear && IsDropDownOpen) if (command == UCM::Command::Clear && IsDropDownOpen)
{ {
return; return;
@ -674,7 +674,7 @@ void UnitConverterViewModel::Deserialize(Platform::String^ state)
RaisePropertyChanged(nullptr); // Update since all props have been updated. RaisePropertyChanged(nullptr); // Update since all props have been updated.
} }
//Saving User Preferences of Category and Associated-Units across Sessions. // Saving User Preferences of Category and Associated-Units across Sessions.
void UnitConverterViewModel::SaveUserPreferences() void UnitConverterViewModel::SaveUserPreferences()
{ {
if (UnitsAreValid()) if (UnitsAreValid())
@ -695,7 +695,7 @@ void UnitConverterViewModel::SaveUserPreferences()
} }
} }
//Restoring User Preferences of Category and Associated-Units. // Restoring User Preferences of Category and Associated-Units.
void UnitConverterViewModel::RestoreUserPreferences() void UnitConverterViewModel::RestoreUserPreferences()
{ {
if (!IsCurrencyCurrentCategory) if (!IsCurrencyCurrentCategory)
@ -973,7 +973,7 @@ void UnitConverterViewModel::OnPaste(String^ stringToPaste, ViewMode mode)
{ {
if (isFirstLegalChar) if (isFirstLegalChar)
{ {
// Send Clear before sending something that will actually apply // Send Clear before sending something that will actually apply
// to the field. // to the field.
m_model->SendCommand(UCM::Command::Clear); m_model->SendCommand(UCM::Command::Clear);
isFirstLegalChar = false; isFirstLegalChar = false;

View file

@ -19,7 +19,7 @@ namespace CalculatorApp
public ref class Category sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged public ref class Category sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{ {
internal: internal:
Category(const UnitConversionManager::Category& category) : Category(const UnitConversionManager::Category& category) :
m_original(category) m_original(category)
{ } { }
@ -52,7 +52,7 @@ namespace CalculatorApp
public ref class Unit sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged public ref class Unit sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{ {
internal: internal:
Unit(const UnitConversionManager::Unit& unit) : Unit(const UnitConversionManager::Unit& unit) :
m_original(unit) m_original(unit)
{ } { }
@ -163,7 +163,7 @@ namespace CalculatorApp
internal: internal:
UnitConverterViewModel(const std::shared_ptr<UnitConversionManager::IUnitConverter>& model); UnitConverterViewModel(const std::shared_ptr<UnitConversionManager::IUnitConverter>& model);
public: public:
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged); OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Category^>^, Categories); OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Category^>^, Categories);
@ -224,7 +224,7 @@ namespace CalculatorApp
COMMAND_FOR_METHOD(PasteCommand, UnitConverterViewModel::OnPasteCommand); COMMAND_FOR_METHOD(PasteCommand, UnitConverterViewModel::OnPasteCommand);
void AnnounceConversionResult(); void AnnounceConversionResult();
internal: internal:
void ResetView(); void ResetView();
void PopulateData(); void PopulateData();
@ -242,8 +242,8 @@ namespace CalculatorApp
void UpdateValue2AutomationName(); void UpdateValue2AutomationName();
Platform::String^ Serialize(); Platform::String^ Serialize();
void Deserialize(Platform::String^ state); void Deserialize(Platform::String^ state);
//Saving And Restoring User Preferences of Category and Associated-Units across Sessions. // Saving And Restoring User Preferences of Category and Associated-Units across Sessions.
void SaveUserPreferences(); void SaveUserPreferences();
void RestoreUserPreferences(); void RestoreUserPreferences();
@ -360,9 +360,9 @@ namespace CalculatorApp
UnitConverterVMCallback(UnitConverterViewModel^ viewModel) : m_viewModel(viewModel) UnitConverterVMCallback(UnitConverterViewModel^ viewModel) : m_viewModel(viewModel)
{} {}
void DisplayCallback(const std::wstring& from, const std::wstring& to) override void DisplayCallback(const std::wstring& from, const std::wstring& to) override
{ {
m_viewModel->UpdateDisplay(from, to); m_viewModel->UpdateDisplay(from, to);
} }
void SuggestedValueCallback( void SuggestedValueCallback(

View file

@ -26,7 +26,7 @@
#include <sstream> #include <sstream>
#include <concrt.h> #include <concrt.h>
#include <regex> #include <regex>
#include <iterator>
// C++\WinRT Headers // C++\WinRT Headers
#include "winrt/base.h" #include "winrt/base.h"
#include "winrt/Windows.Foundation.Diagnostics.h" #include "winrt/Windows.Foundation.Diagnostics.h"

View file

@ -371,12 +371,13 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"/> <VisualState x:Name="Active">
<VisualState x:Name="Normal">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="Light"/> <Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="textContainer"
@ -390,7 +391,7 @@
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
FontWeight="SemiBold" FontWeight="Light"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}" Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -457,12 +458,13 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"/> <VisualState x:Name="Active">
<VisualState x:Name="Normal">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="Light"/> <Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
<Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="textContainer"
@ -476,7 +478,7 @@
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
FontWeight="SemiBold" FontWeight="Light"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}" Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"
@ -544,12 +546,13 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"/> <VisualState x:Name="Active">
<VisualState x:Name="Normal">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="Light"/> <Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="textContainer"
@ -563,7 +566,7 @@
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
FontWeight="SemiBold" FontWeight="Light"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}" Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 384 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 484 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

After

Width:  |  Height:  |  Size: 728 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 234 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 441 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 470 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 511 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 557 B

After

Width:  |  Height:  |  Size: 503 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 683 B

After

Width:  |  Height:  |  Size: 634 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 296 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 331 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

After

Width:  |  Height:  |  Size: 390 B

Before After
Before After

Some files were not shown because too many files have changed in this diff Show more