This commit is contained in:
Stephanie Anderl 2019-02-27 10:19:51 -08:00
commit a342421603
58 changed files with 639 additions and 538 deletions

View file

@ -42,6 +42,9 @@ Want to contribute? The team encourages community feedback and contributions. Pl
If Calculator is not working properly, please file a report in the [Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130). If Calculator is not working properly, please file a report in the [Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130).
We also welcome [issues submitted on GitHub](https://github.com/Microsoft/calculator/issues). We also welcome [issues submitted on GitHub](https://github.com/Microsoft/calculator/issues).
## Roadmap
For information regarding Windows Calculator plans and release schedule, please see the [Windows Calculator Roadmap](docs/Roadmap.md).
## Data / Telemetry ## Data / Telemetry
This project collects usage data and sends it to Microsoft to help improve our products and services. This project collects usage data and sends it to Microsoft to help improve our products and services.
Read our [privacy statement](http://go.microsoft.com/fwlink/?LinkId=521839) to learn more. Read our [privacy statement](http://go.microsoft.com/fwlink/?LinkId=521839) to learn more.
@ -59,7 +62,4 @@ email to ensure we received your original message. Further information, includin
## License ## License
Copyright (c) Microsoft Corporation. All rights reserved. Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [MIT License](.\LICENSE). Licensed under the [MIT License](./LICENSE).
## Contact
Questions that can't be answered on GitHub? Reach out to the team: <[calculator@microsoft.com](mailto:calculator@microsoft.com)>

View file

@ -9,8 +9,8 @@ pr: none
variables: variables:
versionMajor: 10 versionMajor: 10
versionMinor: 1901 versionMinor: 1902
versionBuild: $[counter('10.1901.*', 500)] versionBuild: $[counter('10.1902.*', 0)]
versionPatch: 0 versionPatch: 0
name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)' name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)'

View file

@ -31,6 +31,12 @@ jobs:
env: env:
XES_DISABLEPROV: true XES_DISABLEPROV: true
- task: NuGetToolInstaller@0
displayName: Use NuGet 4.7.1
inputs:
versionSpec: 4.7.1
checkLatest: true
- task: DownloadBuildArtifacts@0 - task: DownloadBuildArtifacts@0
displayName: Download appxBundle artifact displayName: Download appxBundle artifact
inputs: inputs:
@ -96,6 +102,7 @@ jobs:
useArtifactServiceForMedia: true useArtifactServiceForMedia: true
outPath: $(Build.ArtifactStagingDirectory)\StoreBrokerPayload outPath: $(Build.ArtifactStagingDirectory)\StoreBrokerPayload
paToken: $(System.AccessToken) paToken: $(System.AccessToken)
logRootPath: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1
displayName: Publish StoreBrokerPayload artifact displayName: Publish StoreBrokerPayload artifact
@ -103,6 +110,37 @@ jobs:
artifactName: storeBrokerPayload artifactName: storeBrokerPayload
pathToPublish: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload pathToPublish: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload
- task: PkgESStoreBrokerFlight@10
name: StoreBrokerFlight
displayName: Flight package with StoreBroker
env:
XES_SERIALPOSTBUILDREADY: True
inputs:
packageToFlight: Custom
appId: 9WZDNCRFHVN5
flightId: 161f0975-cb5f-475b-8ef6-26383c37621f
submissionDataPath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.json
packagePath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.zip
updatePackageAction: AddPackages
logRootPath: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs
- task: PublishBuildArtifacts@1
displayName: Publish StoreBrokerLogs artifact
inputs:
artifactName: storeBrokerLogs
pathToPublish: $(Build.ArtifactStagingDirectory)/StoreBrokerLogs
- task: PkgESStoreBrokerAeroUpload@10
displayName: Upload to Aero flighting dashboard
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
productId: 00009007199266248474
flightId: 161f0975-cb5f-475b-8ef6-26383c37621f
submissionId: $(StoreBrokerFlight.WS_SubmissionId)
submissionDataPath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.json
packagePath: $(Build.ArtifactStagingDirectory)/StoreBrokerPayload/SBCalculator.zip
- task: PkgESLateTasks@10 - task: PkgESLateTasks@10
displayName: Run PackageES LateTasks displayName: Run PackageES LateTasks
env: env:

View file

@ -277,8 +277,8 @@ Steps:
**All Calculators Test: Hotkeys: Verify Hot Key function.** **All Calculators Test: Hotkeys: Verify Hot Key function.**
Steps: Steps:
1. Launch the "Calculator" app. 1. Launch the "Calculator" app.
For All Applicable Modes:
Verify the following: For All Applicable Modes verify the following:
2. Press **Alt +1** to Enter "Standard" mode 2. Press **Alt +1** to Enter "Standard" mode
*Expected: Move to "Standard" screen.* *Expected: Move to "Standard" screen.*
3. Press **Alt +2** to Enter "Scientific" mode 3. Press **Alt +2** to Enter "Scientific" mode
@ -305,8 +305,9 @@ Verify the following:
*Expected: Function when in small scale window.* *Expected: Function when in small scale window.*
19. Press **Ctrl + Shift + D** to Clear History Panel 19. Press **Ctrl + Shift + D** to Clear History Panel
*Expected: Function when in small scale window.* *Expected: Function when in small scale window.*
20. Press **Spacebar** to Repeat Last Input: 20. Press **Spacebar** to Repeat Last Input
Verify the following in Scientific Mode
Verify the following in Scientific Mode
21. Press **F3** to Select 'DEG' 21. Press **F3** to Select 'DEG'
22. Press **F4** to Select 'RAD' 22. Press **F4** to Select 'RAD'
23. Press **F5** to Select 'GRAD' 23. Press **F5** to Select 'GRAD'
@ -333,7 +334,8 @@ Verify the following in Scientific Mode
44. Press **Y** or **^** to Select 'xʸ' 44. Press **Y** or **^** to Select 'xʸ'
45. Press **#** to Select 'x³' 45. Press **#** to Select 'x³'
46. Press **!** to Select 'n!' 46. Press **!** to Select 'n!'
Verify the following in Programmer Mode
Verify the following in Programmer Mode
47. Press **F2** to Select 'DWORD' 47. Press **F2** to Select 'DWORD'
48. Press **F3** to Select 'WORD' 48. Press **F3** to Select 'WORD'
49. Press **F4** to Select 'BYTE' 49. Press **F4** to Select 'BYTE'
@ -348,6 +350,6 @@ Verify the following in Programmer Mode
58. Press **<** to Select 'Lsh' 58. Press **<** to Select 'Lsh'
59. Press **>** to Select 'Rsh' 59. Press **>** to Select 'Rsh'
60. Press **%** to Select 'Mod' 60. Press **%** to Select 'Mod'
61. Press ** | ** to Select 'Or' 61. Press **|** to Select 'Or'
62. Press **~** to Select 'Not' 62. Press **~** to Select 'Not'
63. Press **&** to Select 'And' 63. Press **&** to Select 'And'

20
docs/Roadmap.md Normal file
View file

@ -0,0 +1,20 @@
# Windows Calculator Roadmap
Windows Calculator is under active development by Microsoft.
## Focus
In 2019, the Windows Calculator team is focused on:
* Refining our open source development process on GitHub
* Iterating upon the existing app design based on the latest [Fluent Design guidelines](https://developer.microsoft.com/en-us/windows/apps/design)
* Improving testing and diagnostics within the project
* Investigating new features with a focus on addressing top user feedback, including:
* Adding the ability for users to pin Calculator on top of other windows
* Providing additional customization options
* [Your feature idea here] - please review our [new feature development process](https://github.com/Microsoft/calculator/blob/master/docs/NewFeatureProcess.md) to get started!
We welcome contributions of all kinds from the community, but especially those that support the efforts above. Please see our [contributing guidelines](https://github.com/Microsoft/calculator/blob/master/CONTRIBUTING.md) for more information on how to get involved.
## Releases
Windows Calculator is included in every Windows 10 release as a [provisioned Windows app](https://docs.microsoft.com/en-us/windows/application-management/apps-in-windows-10#provisioned-windows-apps). We also deliver updates through the [Microsoft Store](https://www.microsoft.com/store/productId/9WZDNCRFHVN5) approximately monthly.

View file

@ -39,7 +39,7 @@ bool CalcInput::TryToggleSign(bool isIntegerMode, wstring_view maxNumStr)
} }
else else
{ {
// When in integer only mode, it isnt always allowed to toggle, as toggling can cause the num to be out of // When in integer only mode, it isn't always allowed to toggle, as toggling can cause the num to be out of
// bounds. For eg. in byte -128 is valid, but when it toggled it becomes 128, which is more than 127. // bounds. For eg. in byte -128 is valid, but when it toggled it becomes 128, which is more than 127.
if (isIntegerMode && m_base.IsNegative()) if (isIntegerMode && m_base.IsNegative())
{ {
@ -59,7 +59,7 @@ bool CalcInput::TryToggleSign(bool isIntegerMode, wstring_view maxNumStr)
bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, long wordBitWidth, int maxDigits) bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, wstring_view maxNumStr, long wordBitWidth, int maxDigits)
{ {
// Convert from an integer into a character // Convert from an integer into a character
// This includes both normal digits and alpha 'digits' for radices > 10 // This includes both normal digits and alpha 'digits' for radixes > 10
auto chDigit = static_cast<wchar_t>((value < 10) ? (L'0' + value) : (L'A' + value - 10)); auto chDigit = static_cast<wchar_t>((value < 10) ? (L'0' + value) : (L'A' + value - 10));
CalcNumSec* pNumSec; CalcNumSec* pNumSec;
@ -74,13 +74,13 @@ bool CalcInput::TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMo
pNumSec = &m_base; pNumSec = &m_base;
maxCount = maxDigits; maxCount = maxDigits;
// Don't include the decimal point in the count. In that way you can enter the maximum allowed precision. // Don't include the decimal point in the count. In that way you can enter the maximum allowed precision.
// Precision doesnt include decimal point. // Precision doesn't include decimal point.
if (HasDecimalPt()) if (HasDecimalPt())
{ {
maxCount++; maxCount++;
} }
// First leading 0 is not counted in input restriction as the output can be of that form // First leading 0 is not counted in input restriction as the output can be of that form
// See NumberToString algorithm. REVIEW: We dont have such input restriction mimicking based on output of NumberToString for exponent // See NumberToString algorithm. REVIEW: We don't have such input restriction mimicking based on output of NumberToString for exponent
// NumberToString can give 10 digit exponent, but we still restrict the exponent here to be only 4 digits. // NumberToString can give 10 digit exponent, but we still restrict the exponent here to be only 4 digits.
if (!pNumSec->IsEmpty() && pNumSec->value.front() == L'0') if (!pNumSec->IsEmpty() && pNumSec->value.front() == L'0')
{ {
@ -307,7 +307,7 @@ Rational CalcInput::ToRational(uint32_t radix, int32_t precision)
PRAT rat = StringToRat(m_base.IsNegative(), m_base.value, m_exponent.IsNegative(), m_exponent.value, radix, precision); PRAT rat = StringToRat(m_base.IsNegative(), m_base.value, m_exponent.IsNegative(), m_exponent.value, radix, precision);
if (rat == nullptr) if (rat == nullptr)
{ {
return Rational{}; return 0;
} }
Rational result{ rat }; Rational result{ rat };

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"
@ -14,8 +14,8 @@ bool IsBinOpCode(WPARAM opCode)
return IsOpInRange(opCode, IDC_AND, IDC_PWR); return IsOpInRange(opCode, IDC_AND, IDC_PWR);
} }
// WARNING: IDC_SIGN is a special unary op but still this doesnt catch this. Caller has to be aware // WARNING: IDC_SIGN is a special unary op but still this doesn't catch this. Caller has to be aware
// of it and catch it themself or not needing this // of it and catch it themselves or not needing this
bool IsUnaryOpCode(WPARAM opCode) bool IsUnaryOpCode(WPARAM opCode)
{ {
return IsOpInRange(opCode, IDC_UNARYFIRST, IDC_UNARYLAST); return IsOpInRange(opCode, IDC_UNARYFIRST, IDC_UNARYLAST);

View file

@ -110,7 +110,7 @@ void CHistoryCollector::RemoveLastOpndFromHistory()
TruncateEquationSzFromIch(m_lastOpStartIndex); TruncateEquationSzFromIch(m_lastOpStartIndex);
SetExpressionDisplay(); SetExpressionDisplay();
m_lastOpStartIndex = -1; m_lastOpStartIndex = -1;
// This will not restore the m_lastBinOpStartIndex, as it isnt possible to remove that also later // This will not restore the m_lastBinOpStartIndex, as it isn't possible to remove that also later
} }
void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool fNoRepetition) void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool fNoRepetition)
@ -129,7 +129,7 @@ void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool fNoRepetition)
} }
// This is expected to be called when a binary op in the last say 1+2+ is changing to another one say 1+2* (+ changed to *) // This is expected to be called when a binary op in the last say 1+2+ is changing to another one say 1+2* (+ changed to *)
// It needs to know by this change a Precedence inversion happenned. i.e. previous op was lower or equal to its previous op, but the new // It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new
// one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^) // one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^)
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher) void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher)
{ {
@ -196,7 +196,7 @@ bool CHistoryCollector::FOpndAddedToHistory()
// AddUnaryOpToHistory // AddUnaryOpToHistory
// //
// This is does the postfix to prefix transalation of the input and adds the text to the history. Eg. doing 2 + 4 (sqrt), // This is does the postfix to prefix translation of the input and adds the text to the history. Eg. doing 2 + 4 (sqrt),
// this routine will ensure the last sqrt call unary operator, actually goes back in history and wraps 4 in sqrt(4) // this routine will ensure the last sqrt call unary operator, actually goes back in history and wraps 4 in sqrt(4)
// //
void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE angletype) void CHistoryCollector::AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE angletype)

View file

@ -2,7 +2,6 @@
#include "pch.h" #include "pch.h"
#include "Header Files/Rational.h" #include "Header Files/Rational.h"
#include "Header Files/scimath.h"
using namespace std; using namespace std;
@ -50,12 +49,12 @@ namespace CalcEngine
destroyrat(pr); destroyrat(pr);
} }
Rational::Rational(uint64_t ui, uint32_t radix, int32_t precision) Rational::Rational(uint64_t ui)
{ {
uint32_t hi = HIDWORD(ui); uint32_t hi = HIDWORD(ui);
uint32_t lo = LODWORD(ui); uint32_t lo = LODWORD(ui);
Rational temp = Rational{ hi }.Lsh(32, radix, precision).Or(lo, radix, precision); Rational temp = (Rational{ hi } << 32) | lo;
m_p = Number{ temp.P() }; m_p = Number{ temp.P() };
m_q = Number{ temp.Q() }; m_q = Number{ temp.Q() };
@ -86,19 +85,19 @@ namespace CalcEngine
return m_q; return m_q;
} }
Rational Rational::Negate() const Rational Rational::operator-() const
{ {
return Rational{ Number{ -1 * m_p.Sign(), m_p.Exp(), m_p.Mantissa() }, m_q}; return Rational{ Number{ -1 * m_p.Sign(), m_p.Exp(), m_p.Mantissa() }, m_q };
} }
Rational Rational::Add(Rational const& rhs, int32_t precision) const Rational& Rational::operator+=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
addrat(&lhsRat, rhsRat, precision); addrat(&lhsRat, rhsRat, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -108,20 +107,20 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Sub(Rational const& rhs, int32_t precision) const Rational& Rational::operator-=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
subrat(&lhsRat, rhsRat, precision); subrat(&lhsRat, rhsRat, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -131,20 +130,20 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Mul(Rational const& rhs, int32_t precision) const Rational& Rational::operator*=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
mulrat(&lhsRat, rhsRat, precision); mulrat(&lhsRat, rhsRat, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -154,20 +153,20 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Div(Rational const& rhs, int32_t precision) const Rational& Rational::operator/=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
divrat(&lhsRat, rhsRat, precision); divrat(&lhsRat, rhsRat, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -177,13 +176,13 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Mod(Rational const& rhs) const Rational& Rational::operator%=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
@ -200,20 +199,20 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Lsh(Rational const& rhs, uint32_t radix, int32_t precision) const Rational& Rational::operator<<=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
lshrat(&lhsRat, rhsRat, radix, precision); lshrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -223,20 +222,20 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Rsh(Rational const& rhs, uint32_t radix, int32_t precision) const Rational& Rational::operator>>=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
rshrat(&lhsRat, rhsRat, radix, precision); rshrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -246,38 +245,20 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Not(bool isIntegerMode, Rational const& chopNum, uint32_t radix, int32_t precision) const Rational& Rational::operator&=(Rational const& rhs)
{
Rational result{};
if (radix == 10 && !isIntegerMode)
{
result = RationalMath::Integer(*this, radix, precision);
result = result.Add(1, precision);
result = result.Negate();
}
else
{
result = this->Xor(chopNum, radix, precision);
}
return result;
}
Rational Rational::And(Rational const& rhs, uint32_t radix, int32_t precision) const
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
andrat(&lhsRat, rhsRat, radix, precision); andrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -287,19 +268,19 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Or(Rational const& rhs, uint32_t radix, int32_t precision) const Rational& Rational::operator|=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
orrat(&lhsRat, rhsRat, radix, precision); orrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -309,19 +290,19 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
Rational Rational::Xor(Rational const& rhs, uint32_t radix, int32_t precision) const Rational& Rational::operator^=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
PRAT rhsRat = rhs.ToPRAT(); PRAT rhsRat = rhs.ToPRAT();
try try
{ {
xorrat(&lhsRat, rhsRat, radix, precision); xorrat(&lhsRat, rhsRat, RATIONAL_BASE, RATIONAL_PRECISION);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (DWORD error) catch (DWORD error)
@ -331,107 +312,136 @@ namespace CalcEngine
throw(error); throw(error);
} }
Rational result = Rational{ lhsRat }; *this = Rational{ lhsRat };
destroyrat(lhsRat); destroyrat(lhsRat);
return result; return *this;
} }
bool Rational::IsZero() const Rational operator+(Rational lhs, Rational const& rhs)
{ {
return this->P().IsZero(); lhs += rhs;
return lhs;
} }
bool Rational::IsLess(Rational const& r, int32_t precision) const Rational operator-(Rational lhs, Rational const& rhs)
{ {
PRAT thisRat = this->ToPRAT(); lhs -= rhs;
PRAT rRat = r.ToPRAT(); return lhs;
}
Rational operator*(Rational lhs, Rational const& rhs)
{
lhs *= rhs;
return lhs;
}
Rational operator/(Rational lhs, Rational const& rhs)
{
lhs /= rhs;
return lhs;
}
Rational operator%(Rational lhs, Rational const& rhs)
{
lhs %= rhs;
return lhs;
}
Rational operator<<(Rational lhs, Rational const& rhs)
{
lhs <<= rhs;
return lhs;
}
Rational operator>>(Rational lhs, Rational const& rhs)
{
lhs >>= rhs;
return lhs;
}
Rational operator&(Rational lhs, Rational const& rhs)
{
lhs &= rhs;
return lhs;
}
Rational operator|(Rational lhs, Rational const& rhs)
{
lhs |= rhs;
return lhs;
}
Rational operator^(Rational lhs, Rational const& rhs)
{
lhs ^= rhs;
return lhs;
}
bool operator==(Rational const& lhs, Rational const& rhs)
{
PRAT lhsRat = lhs.ToPRAT();
PRAT rhsRat = rhs.ToPRAT();
bool result = false; bool result = false;
try try
{ {
result = rat_lt(thisRat, rRat, precision); result = rat_equ(lhsRat, rhsRat, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
destroyrat(thisRat); destroyrat(lhsRat);
destroyrat(rRat); destroyrat(rhsRat);
throw(error); throw(error);
} }
destroyrat(thisRat); destroyrat(lhsRat);
destroyrat(rRat); destroyrat(rhsRat);
return result; return result;
} }
bool Rational::IsLessEq(Rational const& r, int32_t precision) const bool operator!=(Rational const& lhs, Rational const& rhs)
{ {
PRAT thisRat = this->ToPRAT(); return !(lhs == rhs);
PRAT rRat = r.ToPRAT(); }
bool operator<(Rational const& lhs, Rational const& rhs)
{
PRAT lhsRat = lhs.ToPRAT();
PRAT rhsRat = rhs.ToPRAT();
bool result = false; bool result = false;
try try
{ {
result = rat_le(thisRat, rRat, precision); result = rat_lt(lhsRat, rhsRat, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
destroyrat(thisRat); destroyrat(lhsRat);
destroyrat(rRat); destroyrat(rhsRat);
throw(error); throw(error);
} }
destroyrat(thisRat); destroyrat(lhsRat);
destroyrat(rRat); destroyrat(rhsRat);
return result; return result;
} }
bool Rational::IsGreaterEq(Rational const& r, int32_t precision) const bool operator>(Rational const& lhs, Rational const& rhs)
{ {
PRAT thisRat = this->ToPRAT(); return rhs < lhs;
PRAT rRat = r.ToPRAT();
bool result = false;
try
{
result = rat_ge(thisRat, rRat, precision);
}
catch (DWORD error)
{
destroyrat(thisRat);
destroyrat(rRat);
throw(error);
} }
destroyrat(thisRat); bool operator<=(Rational const& lhs, Rational const& rhs)
destroyrat(rRat); {
return !(lhs > rhs);
return result;
} }
bool Rational::IsEq(Rational const& r, int32_t precision) const bool operator>=(Rational const& lhs, Rational const& rhs)
{ {
PRAT thisRat = this->ToPRAT(); return !(lhs < rhs);
PRAT rRat = r.ToPRAT();
bool result = false;
try
{
result = rat_equ(thisRat, rRat, precision);
}
catch (DWORD error)
{
destroyrat(thisRat);
destroyrat(rRat);
throw(error);
}
destroyrat(thisRat);
destroyrat(rRat);
return result;
} }
wstring Rational::ToString(uint32_t radix, NUMOBJ_FMT fmt, int32_t precision) const wstring Rational::ToString(uint32_t radix, NUMOBJ_FMT fmt, int32_t precision) const
@ -454,13 +464,13 @@ namespace CalcEngine
return result; return result;
} }
uint64_t Rational::ToUInt64_t(uint32_t radix, int32_t precision) const uint64_t Rational::ToUInt64_t() const
{ {
PRAT rat = this->ToPRAT(); PRAT rat = this->ToPRAT();
uint64_t result; uint64_t result;
try try
{ {
result = rattoUlonglong(rat, radix, precision); result = rattoUlonglong(rat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {

View file

@ -2,18 +2,17 @@
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/RationalMath.h"
#include "Ratpack/ratpak.h"
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
Rational RationalMath::Frac(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::Frac(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
fracrat(&prat, radix, precision); fracrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -27,12 +26,12 @@ Rational RationalMath::Frac(Rational const& rat, uint32_t radix, int32_t precisi
return result; return result;
} }
Rational RationalMath::Integer(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::Integer(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
intrat(&prat, radix, precision); intrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -46,14 +45,14 @@ Rational RationalMath::Integer(Rational const& rat, uint32_t radix, int32_t prec
return result; return result;
} }
Rational RationalMath::Pow(Rational const& base, Rational const& pow, uint32_t radix, int32_t precision) Rational RationalMath::Pow(Rational const& base, Rational const& pow)
{ {
PRAT baseRat = base.ToPRAT(); PRAT baseRat = base.ToPRAT();
PRAT powRat = pow.ToPRAT(); PRAT powRat = pow.ToPRAT();
try try
{ {
powrat(&baseRat, powRat, radix, precision); powrat(&baseRat, powRat, RATIONAL_BASE, RATIONAL_PRECISION);
destroyrat(powRat); destroyrat(powRat);
} }
catch (DWORD error) catch (DWORD error)
@ -69,18 +68,18 @@ Rational RationalMath::Pow(Rational const& base, Rational const& pow, uint32_t r
return result; return result;
} }
Rational RationalMath::Root(Rational const& base, Rational const& root, uint32_t radix, int32_t precision) Rational RationalMath::Root(Rational const& base, Rational const& root)
{ {
return Pow(base, Invert(root, precision), radix, precision); return Pow(base, Invert(root));
} }
Rational RationalMath::Fact(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::Fact(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
factrat(&prat, radix, precision); factrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -94,13 +93,13 @@ Rational RationalMath::Fact(Rational const& rat, uint32_t radix, int32_t precisi
return result; return result;
} }
Rational RationalMath::Exp(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::Exp(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
exprat(&prat, radix, precision); exprat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -114,13 +113,13 @@ Rational RationalMath::Exp(Rational const& rat, uint32_t radix, int32_t precisio
return result; return result;
} }
Rational RationalMath::Log(Rational const& rat, int32_t precision) Rational RationalMath::Log(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
lograt(&prat, precision); lograt(&prat, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -134,14 +133,14 @@ Rational RationalMath::Log(Rational const& rat, int32_t precision)
return result; return result;
} }
Rational RationalMath::Log10(Rational const& rat, int32_t precision) Rational RationalMath::Log10(Rational const& rat)
{ {
return Log(rat, precision).Div(10, precision); return Log(rat) / Rational{ ln_ten };
} }
Rational RationalMath::Invert(Rational const& rat, int32_t precision) Rational RationalMath::Invert(Rational const& rat)
{ {
return Rational{ 1 }.Div(rat, precision); return 1 / rat;
} }
Rational RationalMath::Abs(Rational const& rat) Rational RationalMath::Abs(Rational const& rat)
@ -149,13 +148,13 @@ Rational RationalMath::Abs(Rational const& rat)
return Rational{ Number{ 1, rat.P().Exp(), rat.P().Mantissa() }, Number{ 1, rat.Q().Exp(), rat.Q().Mantissa() } }; return Rational{ Number{ 1, rat.P().Exp(), rat.P().Mantissa() }, Number{ 1, rat.Q().Exp(), rat.Q().Mantissa() } };
} }
Rational RationalMath::Sin(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision) Rational RationalMath::Sin(Rational const& rat, ANGLE_TYPE angletype)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
sinanglerat(&prat, angletype, radix, precision); sinanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -169,13 +168,13 @@ Rational RationalMath::Sin(Rational const& rat, ANGLE_TYPE angletype, uint32_t r
return result; return result;
} }
Rational RationalMath::Cos(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision) Rational RationalMath::Cos(Rational const& rat, ANGLE_TYPE angletype)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
cosanglerat(&prat, angletype, radix, precision); cosanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -189,13 +188,13 @@ Rational RationalMath::Cos(Rational const& rat, ANGLE_TYPE angletype, uint32_t r
return result; return result;
} }
Rational RationalMath::Tan(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision) Rational RationalMath::Tan(Rational const& rat, ANGLE_TYPE angletype)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
tananglerat(&prat, angletype, radix, precision); tananglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -209,13 +208,13 @@ Rational RationalMath::Tan(Rational const& rat, ANGLE_TYPE angletype, uint32_t r
return result; return result;
} }
Rational RationalMath::ASin(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision) Rational RationalMath::ASin(Rational const& rat, ANGLE_TYPE angletype)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
asinanglerat(&prat, angletype, radix, precision); asinanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -229,13 +228,13 @@ Rational RationalMath::ASin(Rational const& rat, ANGLE_TYPE angletype, uint32_t
return result; return result;
} }
Rational RationalMath::ACos(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision) Rational RationalMath::ACos(Rational const& rat, ANGLE_TYPE angletype)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
acosanglerat(&prat, angletype, radix, precision); acosanglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -249,13 +248,13 @@ Rational RationalMath::ACos(Rational const& rat, ANGLE_TYPE angletype, uint32_t
return result; return result;
} }
Rational RationalMath::ATan(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision) Rational RationalMath::ATan(Rational const& rat, ANGLE_TYPE angletype)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
atananglerat(&prat, angletype, radix, precision); atananglerat(&prat, angletype, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -269,13 +268,13 @@ Rational RationalMath::ATan(Rational const& rat, ANGLE_TYPE angletype, uint32_t
return result; return result;
} }
Rational RationalMath::Sinh(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::Sinh(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
sinhrat(&prat, radix, precision); sinhrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -289,13 +288,13 @@ Rational RationalMath::Sinh(Rational const& rat, uint32_t radix, int32_t precisi
return result; return result;
} }
Rational RationalMath::Cosh(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::Cosh(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
coshrat(&prat, radix, precision); coshrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -309,13 +308,13 @@ Rational RationalMath::Cosh(Rational const& rat, uint32_t radix, int32_t precisi
return result; return result;
} }
Rational RationalMath::Tanh(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::Tanh(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
tanhrat(&prat, radix, precision); tanhrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -329,13 +328,13 @@ Rational RationalMath::Tanh(Rational const& rat, uint32_t radix, int32_t precisi
return result; return result;
} }
Rational RationalMath::ASinh(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::ASinh(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
asinhrat(&prat, radix, precision); asinhrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -349,13 +348,13 @@ Rational RationalMath::ASinh(Rational const& rat, uint32_t radix, int32_t precis
return result; return result;
} }
Rational RationalMath::ACosh(Rational const& rat, uint32_t radix, int32_t precision) Rational RationalMath::ACosh(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
acoshrat(&prat, radix, precision); acoshrat(&prat, RATIONAL_BASE, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {
@ -369,13 +368,13 @@ Rational RationalMath::ACosh(Rational const& rat, uint32_t radix, int32_t precis
return result; return result;
} }
Rational RationalMath::ATanh(Rational const& rat, int32_t precision) Rational RationalMath::ATanh(Rational const& rat)
{ {
PRAT prat = rat.ToPRAT(); PRAT prat = rat.ToPRAT();
try try
{ {
atanhrat(&prat, precision); atanhrat(&prat, RATIONAL_PRECISION);
} }
catch (DWORD error) catch (DWORD error)
{ {

View file

@ -44,7 +44,7 @@ void CCalcEngine::InitialOneTimeOnlySetup(CalculationManager::IResourceProvider&
{ {
LoadEngineStrings(resourceProvider); LoadEngineStrings(resourceProvider);
// we must now setup all the ratpak constants and our arrayed pointers // we must now set up all the ratpak constants and our arrayed pointers
// to these constants. // to these constants.
ChangeBaseConstants(DEFAULT_RADIX, DEFAULT_MAX_DIGITS, DEFAULT_PRECISION); ChangeBaseConstants(DEFAULT_RADIX, DEFAULT_MAX_DIGITS, DEFAULT_PRECISION);
} }
@ -65,7 +65,7 @@ CCalcEngine::CCalcEngine(bool fPrecedence, bool fIntegerMode, CalculationManager
m_nOpCode(0), m_nOpCode(0),
m_nPrevOpCode(0), m_nPrevOpCode(0),
m_openParenCount(0), m_openParenCount(0),
m_nPrecNum(0), m_precedenceOpCount(0),
m_nTempCom(0), m_nTempCom(0),
m_nLastCom(0), m_nLastCom(0),
m_parenVals{}, m_parenVals{},
@ -95,7 +95,7 @@ CCalcEngine::CCalcEngine(bool fPrecedence, bool fIntegerMode, CalculationManager
m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(m_numwidth); m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(m_numwidth);
m_maxTrigonometricNum = RationalMath::Pow(10, 100, m_radix, m_precision); m_maxTrigonometricNum = RationalMath::Pow(10, 100);
SetRadixTypeAndNumWidth(DEC_RADIX, m_numwidth); SetRadixTypeAndNumWidth(DEC_RADIX, m_numwidth);
SettingsChanged(); SettingsChanged();
@ -112,13 +112,13 @@ void CCalcEngine::InitChopNumbers()
m_chopNumbers[2] = Rational{ rat_word }; m_chopNumbers[2] = Rational{ rat_word };
m_chopNumbers[3] = Rational{ rat_byte }; m_chopNumbers[3] = Rational{ rat_byte };
// initialize the max dec number you can support for each of the supported bit length // initialize the max dec number you can support for each of the supported bit lengths
// this is basically max num in that width / 2 in integer // this is basically max num in that width / 2 in integer
assert(m_chopNumbers.size() == m_maxDecimalValueStrings.size()); assert(m_chopNumbers.size() == m_maxDecimalValueStrings.size());
for (size_t i = 0; i < m_chopNumbers.size(); i++) for (size_t i = 0; i < m_chopNumbers.size(); i++)
{ {
auto maxVal = m_chopNumbers[i].Div(2, m_precision); auto maxVal = m_chopNumbers[i] / 2;
maxVal = RationalMath::Integer(maxVal, m_radix, m_precision); maxVal = RationalMath::Integer(maxVal);
m_maxDecimalValueStrings[i] = maxVal.ToString(10, FMT_FLOAT, m_precision); m_maxDecimalValueStrings[i] = maxVal.ToString(10, FMT_FLOAT, m_precision);
} }

View file

@ -4,7 +4,7 @@
/****************************Module*Header***********************************\ /****************************Module*Header***********************************\
* Module Name: SCICOMM.C * Module Name: SCICOMM.C
* *
* Module Descripton: * Module Description:
* *
* Warnings: * Warnings:
* *
@ -28,8 +28,8 @@ using namespace CalcEngine;
// NPrecedenceOfOp // NPrecedenceOfOp
// //
// returns a virtual number for precendence for the operator. We expect binary operator only, otherwise the lowest number // 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 precendence of the operator. // 0 is returned. Higher the number, higher the precedence of the operator.
INT NPrecedenceOfOp(int nopCode) INT NPrecedenceOfOp(int nopCode)
{ {
static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1, static BYTE rgbPrec[] = { 0,0, IDC_OR,0, IDC_XOR,0, IDC_AND,1,
@ -53,12 +53,12 @@ INT NPrecedenceOfOp(int nopCode)
// 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
// occured 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 unremember this state // we would have saved the prev command. Need to forget this state
m_nTempCom = m_nLastCom; m_nTempCom = m_nLastCom;
} }
} }
@ -184,23 +184,23 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
if (IsBinOpCode(m_nLastCom)) if (IsBinOpCode(m_nLastCom))
{ {
INT nPrev; INT nPrev;
bool fPrecInvToHigher = false; // Is Precedence Invertion from lower to higher precedence happenning ?? bool fPrecInvToHigher = false; // Is Precedence Inversion from lower to higher precedence happening ??
m_nOpCode = (INT)wParam; m_nOpCode = (INT)wParam;
// Check to see if by changing this binop, a Precedence invertion is happenning. // Check to see if by changing this binop, a Precedence inversion is happening.
// Eg. 1 * 2 + and + is getting changed to ^. The previous precedence rules would have already computed // Eg. 1 * 2 + and + is getting changed to ^. The previous precedence rules would have already computed
// 1*2, so we will put additional brackets to cover for precedence invertion and it will become (1 * 2) ^ // 1*2, so we will put additional brackets to cover for precedence inversion and it will become (1 * 2) ^
// Here * is m_nPrevOpCode, m_currentVal is 2 (by 1*2), m_nLastCom is +, m_nOpCode is ^ // Here * is m_nPrevOpCode, m_currentVal is 2 (by 1*2), m_nLastCom is +, m_nOpCode is ^
if (m_fPrecedence && 0 != m_nPrevOpCode) if (m_fPrecedence && 0 != m_nPrevOpCode)
{ {
nPrev = NPrecedenceOfOp(m_nPrevOpCode); nPrev = NPrecedenceOfOp(m_nPrevOpCode);
nx = NPrecedenceOfOp(m_nLastCom); nx = NPrecedenceOfOp(m_nLastCom);
ni = NPrecedenceOfOp(m_nOpCode); ni = NPrecedenceOfOp(m_nOpCode);
if (nx <= nPrev && ni > nPrev) // condition for Precedence Invertion if (nx <= nPrev && ni > nPrev) // condition for Precedence Inversion
{ {
fPrecInvToHigher = true; fPrecInvToHigher = true;
m_nPrevOpCode = 0; // Once the precedence invertion has put additional brackets, its no longer required m_nPrevOpCode = 0; // Once the precedence inversion has put additional brackets, its no longer required
} }
} }
m_HistoryCollector.ChangeLastBinOp(m_nOpCode, fPrecInvToHigher); m_HistoryCollector.ChangeLastBinOp(m_nOpCode, fPrecInvToHigher);
@ -228,19 +228,19 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
if ((nx > ni) && m_fPrecedence) if ((nx > ni) && m_fPrecedence)
{ {
if (m_nPrecNum < MAXPRECDEPTH) if (m_precedenceOpCount < MAXPRECDEPTH)
{ {
m_precedenceVals[m_nPrecNum] = m_lastVal; m_precedenceVals[m_precedenceOpCount] = m_lastVal;
m_nPrecOp[m_nPrecNum] = m_nOpCode; m_nPrecOp[m_precedenceOpCount] = m_nOpCode;
m_HistoryCollector.PushLastOpndStart(); // Eg. 1 + 2 *, Need to remember the start of 2 to do Precedence invertion if need to m_HistoryCollector.PushLastOpndStart(); // Eg. 1 + 2 *, Need to remember the start of 2 to do Precedence inversion if need to
} }
else else
{ {
m_nPrecNum = MAXPRECDEPTH - 1; m_precedenceOpCount = MAXPRECDEPTH - 1;
HandleErrorCommand(wParam); HandleErrorCommand(wParam);
} }
m_nPrecNum++; m_precedenceOpCount++;
} }
else else
{ {
@ -256,18 +256,18 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
DisplayNum(); DisplayNum();
} }
if ((m_nPrecNum != 0) && (m_nPrecOp[m_nPrecNum - 1])) if ((m_precedenceOpCount != 0) && (m_nPrecOp[m_precedenceOpCount - 1]))
{ {
m_nPrecNum--; m_precedenceOpCount--;
m_nOpCode = m_nPrecOp[m_nPrecNum]; m_nOpCode = m_nPrecOp[m_precedenceOpCount];
m_lastVal = m_precedenceVals[m_nPrecNum]; m_lastVal = m_precedenceVals[m_precedenceOpCount];
nx = NPrecedenceOfOp(m_nOpCode); nx = NPrecedenceOfOp(m_nOpCode);
// Precedence Invertion Higher to lower can happen which needs explicit enclosure of brackets // Precedence Inversion Higher to lower can happen which needs explicit enclosure of brackets
// Eg. 1 + 2 * Or 3 Or. We would have pushed 1+ before, and now last + forces 2 Or 3 to be evaluated // Eg. 1 + 2 * Or 3 Or. We would have pushed 1+ before, and now last + forces 2 Or 3 to be evaluated
// because last Or is less or equal to first + (after 1). But we see that 1+ is in stack and we evaluated to 2 Or 3 // because last Or is less or equal to first + (after 1). But we see that 1+ is in stack and we evaluated to 2 Or 3
// This is precedence invertion happenned because of operator changed in between. We put extra brackets like // This is precedence inversion happened because of operator changed in between. We put extra brackets like
// 1 + (2 Or 3) // 1 + (2 Or 3)
if (ni <= nx) if (ni <= nx)
{ {
@ -318,6 +318,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
{ {
if (IsCurrentTooBigForTrig()) if (IsCurrentTooBigForTrig())
{ {
m_currentVal = 0;
DisplayError(CALC_E_DOMAIN); DisplayError(CALC_E_DOMAIN);
return; return;
} }
@ -382,10 +383,10 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
CheckAndAddLastBinOpToHistory(false); CheckAndAddLastBinOpToHistory(false);
} }
m_lastVal = Rational{}; m_lastVal = 0;
m_bChangeOp = false; m_bChangeOp = false;
m_nPrecNum = m_nTempCom = m_nLastCom = m_nOpCode = m_openParenCount = 0; m_precedenceOpCount = m_nTempCom = m_nLastCom = m_nOpCode = m_openParenCount = 0;
m_nPrevOpCode = 0; m_nPrevOpCode = 0;
m_bNoPrevEqu = true; m_bNoPrevEqu = true;
@ -435,7 +436,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
{ {
break; break;
} }
// automatic closing of all the parenthesis to get a meaning ful result as well as ensure data integrity // automatic closing of all the parenthesis to get a meaningful result as well as ensure data integrity
m_nTempCom = m_nLastCom; // Put back this last saved command to the prev state so ) can be handled properly m_nTempCom = m_nLastCom; // Put back this last saved command to the prev state so ) can be handled properly
ProcessCommand(IDC_CLOSEP); ProcessCommand(IDC_CLOSEP);
m_nLastCom = m_nTempCom; // Actually this is IDC_CLOSEP m_nLastCom = m_nTempCom; // Actually this is IDC_CLOSEP
@ -444,7 +445,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
if (!m_bNoPrevEqu) if (!m_bNoPrevEqu)
{ {
// It is possible now unary op changed the num in screen, but still m_lastVal hasnt changed. // It is possible now unary op changed the num in screen, but still m_lastVal hasn't changed.
m_lastVal = m_currentVal; m_lastVal = m_currentVal;
} }
@ -495,13 +496,13 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
else if (!m_bError) else if (!m_bError)
DisplayNum(); DisplayNum();
if (m_nPrecNum == 0 || !m_fPrecedence) if (m_precedenceOpCount == 0 || !m_fPrecedence)
break; break;
m_nOpCode = m_nPrecOp[--m_nPrecNum]; m_nOpCode = m_nPrecOp[--m_precedenceOpCount];
m_lastVal = m_precedenceVals[m_nPrecNum]; m_lastVal = m_precedenceVals[m_precedenceOpCount];
// Precedence Invertion check // Precedence Inversion check
ni = NPrecedenceOfOp(m_nPrevOpCode); ni = NPrecedenceOfOp(m_nPrevOpCode);
nx = NPrecedenceOfOp(m_nOpCode); nx = NPrecedenceOfOp(m_nOpCode);
if (ni <= nx) if (ni <= nx)
@ -511,7 +512,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
m_HistoryCollector.PopLastOpndStart(); m_HistoryCollector.PopLastOpndStart();
m_bNoPrevEqu = true; m_bNoPrevEqu = true;
} while (m_nPrecNum >= 0); } while (m_precedenceOpCount >= 0);
if (!m_bError) if (!m_bError)
{ {
@ -539,9 +540,9 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
// -IF- the Paren holding array is full and we try to add a paren // -IF- the Paren holding array is full and we try to add a paren
// -OR- the paren holding array is empty and we try to remove a // -OR- the paren holding array is empty and we try to remove a
// paren // paren
// -OR- the the precidence holding array is full // -OR- the precedence holding array is full
if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx) if ((m_openParenCount >= MAXPRECDEPTH && nx) || (!m_openParenCount && !nx)
|| ((m_nPrecNum >= MAXPRECDEPTH && m_nPrecOp[m_nPrecNum - 1] != 0))) || ((m_precedenceOpCount >= MAXPRECDEPTH && m_nPrecOp[m_precedenceOpCount - 1] != 0)))
{ {
HandleErrorCommand(wParam); HandleErrorCommand(wParam);
break; break;
@ -558,17 +559,17 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
m_nOp[m_openParenCount++] = (m_bChangeOp ? m_nOpCode : 0); m_nOp[m_openParenCount++] = (m_bChangeOp ? m_nOpCode : 0);
/* save a special marker on the precedence array */ /* save a special marker on the precedence array */
if (m_nPrecNum < m_nPrecOp.size()) if (m_precedenceOpCount < m_nPrecOp.size())
{ {
m_nPrecOp[m_nPrecNum++] = 0; m_nPrecOp[m_precedenceOpCount++] = 0;
} }
m_lastVal = Rational{}; 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 = Rational{}; m_currentVal = 0;
} }
m_nTempCom = 0; m_nTempCom = 0;
m_nOpCode = 0; m_nOpCode = 0;
@ -592,7 +593,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
m_nPrevOpCode = m_nOpCode; m_nPrevOpCode = m_nOpCode;
// Now process the precedence stack till we get to an opcode which is zero. // Now process the precedence stack till we get to an opcode which is zero.
for (m_nOpCode = m_nPrecOp[--m_nPrecNum]; m_nOpCode; m_nOpCode = m_nPrecOp[--m_nPrecNum]) for (m_nOpCode = m_nPrecOp[--m_precedenceOpCount]; m_nOpCode; m_nOpCode = m_nPrecOp[--m_precedenceOpCount])
{ {
// Precedence Inversion check // Precedence Inversion check
ni = NPrecedenceOfOp(m_nPrevOpCode); ni = NPrecedenceOfOp(m_nPrevOpCode);
@ -603,7 +604,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
} }
m_HistoryCollector.PopLastOpndStart(); m_HistoryCollector.PopLastOpndStart();
m_lastVal = m_precedenceVals[m_nPrecNum]; m_lastVal = m_precedenceVals[m_precedenceOpCount];
m_currentVal = DoOperation(m_nOpCode, m_currentVal, m_lastVal); m_currentVal = DoOperation(m_nOpCode, m_currentVal, m_lastVal);
m_nPrevOpCode = m_nOpCode; m_nPrevOpCode = m_nOpCode;
@ -611,7 +612,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
m_HistoryCollector.AddCloseBraceToHistory(); m_HistoryCollector.AddCloseBraceToHistory();
// Now get back the operation and opcode at the begining of this parenthesis pair // Now get back the operation and opcode at the beginning of this parenthesis pair
m_openParenCount -= 1; m_openParenCount -= 1;
m_lastVal = m_parenVals[m_openParenCount]; m_lastVal = m_parenVals[m_openParenCount];
@ -691,7 +692,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal);
} }
m_currentVal = m_currentVal.Negate(); m_currentVal = -(m_currentVal);
DisplayNum(); DisplayNum();
m_HistoryCollector.AddUnaryOpToHistory(IDC_SIGN, m_bInv, m_angletype); m_HistoryCollector.AddUnaryOpToHistory(IDC_SIGN, m_bInv, m_angletype);
@ -708,7 +709,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
else else
{ {
// Recall immediate memory value. // Recall immediate memory value.
m_currentVal = Rational{ *m_memoryValue }; m_currentVal = *m_memoryValue;
} }
CheckAndAddLastBinOpToHistory(); CheckAndAddLastBinOpToHistory();
DisplayNum(); DisplayNum();
@ -718,7 +719,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
{ {
/* MPLUS adds m_currentVal to immediate memory and kills the "mem" */ /* MPLUS adds m_currentVal to immediate memory and kills the "mem" */
/* indicator if the result is zero. */ /* indicator if the result is zero. */
Rational result = m_memoryValue->Add(m_currentVal, m_precision); Rational result = *m_memoryValue + m_currentVal;
m_memoryValue = make_unique<Rational>(TruncateNumForIntMath(result)); // Memory should follow the current int mode m_memoryValue = make_unique<Rational>(TruncateNumForIntMath(result)); // Memory should follow the current int mode
break; break;
@ -727,14 +728,14 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam)
{ {
/* MMINUS subtracts m_currentVal to immediate memory and kills the "mem" */ /* MMINUS subtracts m_currentVal to immediate memory and kills the "mem" */
/* indicator if the result is zero. */ /* indicator if the result is zero. */
Rational result = m_memoryValue->Sub(m_currentVal, m_precision); Rational result = *m_memoryValue - m_currentVal;
m_memoryValue = make_unique<Rational>(TruncateNumForIntMath(result)); m_memoryValue = make_unique<Rational>(TruncateNumForIntMath(result));
break; break;
} }
case IDC_STORE: case IDC_STORE:
case IDC_MCLEAR: case IDC_MCLEAR:
m_memoryValue = make_unique<Rational>(wParam == IDC_STORE ? TruncateNumForIntMath(m_currentVal) : Rational{}); m_memoryValue = make_unique<Rational>(wParam == IDC_STORE ? TruncateNumForIntMath(m_currentVal) : 0);
break; break;
case IDC_PI: case IDC_PI:
@ -795,7 +796,7 @@ void CCalcEngine::CheckAndAddLastBinOpToHistory(bool addToHistory)
{ {
if (m_HistoryCollector.FOpndAddedToHistory()) if (m_HistoryCollector.FOpndAddedToHistory())
{ {
// if lasttime 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
@ -826,7 +827,7 @@ void CCalcEngine::CheckAndAddLastBinOpToHistory(bool addToHistory)
} }
// change the display area from a static text to an editbox, which has the focus can make // change the display area from a static text to an editbox, which has the focus can make
// Magnifer (Accessibility tool) work // Magnifier (Accessibility tool) work
void CCalcEngine::SetPrimaryDisplay(const wstring& szText, bool isError) void CCalcEngine::SetPrimaryDisplay(const wstring& szText, bool isError)
{ {
if (m_pCalcDisplay != nullptr) if (m_pCalcDisplay != nullptr)
@ -847,8 +848,8 @@ void CCalcEngine::DisplayAnnounceBinaryOperator()
} }
// Unary operator Function Name table Element // Unary operator Function Name table Element
// since unary operators button names are'nt exactly friendly for history purpose, // since unary operators button names aren't exactly friendly for history purpose,
// we have this seperate 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
{ {
int idsFunc; // index of string for the unary op function. Can be NULL, in which case it same as button name int idsFunc; // index of string for the unary op function. Can be NULL, in which case it same as button name
@ -904,7 +905,7 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
return GetString(IDS_DEGREES); return GetString(IDS_DEGREES);
} }
// Correct the trigometric functions with type of angle argument they take // Correct the trigonometric functions with type of angle argument they take
if (ANGLE_RAD == angletype) if (ANGLE_RAD == angletype)
{ {
switch (nOpCode) switch (nOpCode)
@ -962,7 +963,7 @@ wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE
// //
// Sets the Angle Mode for special unary op IDC's which are used to index to the table rgUfne // Sets the Angle Mode for special unary op IDC's which are used to index to the table rgUfne
// and returns the equivalent plain IDC for trignometric function. If it isnt a trignometric function // and returns the equivalent plain IDC for trigonometric function. If it isn't a trigonometric function
// returns the passed in idc itself. // returns the passed in idc itself.
int CCalcEngine::IdcSetAngleTypeDecMode(int idc) int CCalcEngine::IdcSetAngleTypeDecMode(int idc)
{ {
@ -1002,13 +1003,7 @@ int CCalcEngine::IdcSetAngleTypeDecMode(int idc)
bool CCalcEngine::IsCurrentTooBigForTrig() bool CCalcEngine::IsCurrentTooBigForTrig()
{ {
if (m_currentVal.IsGreaterEq(m_maxTrigonometricNum, m_precision)) return m_currentVal >= m_maxTrigonometricNum;
{
m_currentVal = Rational{};
return true;
}
return false;
} }
int CCalcEngine::GetCurrentRadix() int CCalcEngine::GetCurrentRadix()
@ -1048,14 +1043,12 @@ wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix)
try try
{ {
uint64_t w64Bits = tempRat.ToUInt64_t(m_radix, m_precision); uint64_t w64Bits = tempRat.ToUInt64_t();
bool fMsb = ((w64Bits >> (m_dwWordBitWidth - 1)) & 1); bool fMsb = ((w64Bits >> (m_dwWordBitWidth - 1)) & 1);
if ((radix == 10) && fMsb) if ((radix == 10) && fMsb)
{ {
// If high bit is set, then get the decimal number in negative 2's compl form. // If high bit is set, then get the decimal number in negative 2's complement form.
tempRat = tempRat.Not(true, m_chopNumbers[m_numwidth], m_radix, m_precision); tempRat = -((tempRat ^ m_chopNumbers[m_numwidth]) + 1);
tempRat = tempRat.Add(1, m_precision);
tempRat = tempRat.Negate();
} }
result = tempRat.ToString(radix, m_nFE, m_precision); result = tempRat.ToString(radix, m_nFE, m_precision);

View file

@ -4,7 +4,7 @@
/****************************Module*Header***********************************\ /****************************Module*Header***********************************\
* Module Name: SCIDISP.C * Module Name: SCIDISP.C
* *
* Module Descripton: * Module Description:
* *
* Warnings: * Warnings:
* *
@ -57,19 +57,18 @@ CalcEngine::Rational CCalcEngine::TruncateNumForIntMath(CalcEngine::Rational con
} }
// Truncate to an integer. Do not round here. // Truncate to an integer. Do not round here.
auto result = RationalMath::Integer(rat, m_radix, m_precision); auto result = RationalMath::Integer(rat);
// Can be converting a dec negative number to Hex/Oct/Bin rep. Use 2's complement form // Can be converting a dec negative number to Hex/Oct/Bin rep. Use 2's complement form
// Check the range. // Check the range.
if (result.IsLess(0, m_precision)) if (result < 0)
{ {
// if negative make positive by doing a twos complement // if negative make positive by doing a twos complement
result = result.Negate(); result = -(result) - 1;
result = result.Sub(1, m_precision); result ^= m_chopNumbers[m_numwidth];
result = result.Not(true /* IntegerMode */, m_chopNumbers[m_numwidth], m_radix, m_precision);
} }
result = result.And(m_chopNumbers[m_numwidth], m_radix, m_precision); result &= m_chopNumbers[m_numwidth];
return result; return result;
} }
@ -84,7 +83,7 @@ void CCalcEngine::DisplayNum(void)
// called. // called.
// //
if (m_bRecord || if (m_bRecord ||
!gldPrevious.value.IsEq(m_currentVal, m_precision) || gldPrevious.value != m_currentVal ||
gldPrevious.precision != m_precision || gldPrevious.precision != m_precision ||
gldPrevious.radix != m_radix || gldPrevious.radix != m_radix ||
gldPrevious.nFE != (int)m_nFE || gldPrevious.nFE != (int)m_nFE ||
@ -117,7 +116,7 @@ void CCalcEngine::DisplayNum(void)
m_numberString = GetStringForDisplay(m_currentVal, m_radix); m_numberString = GetStringForDisplay(m_currentVal, m_radix);
} }
// Displayed number can go thru transformation. So copy it after transformation // Displayed number can go through transformation. So copy it after transformation
gldPrevious.value = m_currentVal; gldPrevious.value = m_currentVal;
if ((m_radix == 10) && IsNumberInvalid(m_numberString, MAX_EXPONENT, m_precision, m_radix)) if ((m_radix == 10) && IsNumberInvalid(m_numberString, MAX_EXPONENT, m_precision, m_radix))

View file

@ -32,26 +32,33 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
switch (op) switch (op)
{ {
case IDC_CHOP: case IDC_CHOP:
result = m_bInv ? Frac(rat, m_radix, m_precision) : Integer(rat, m_radix, m_precision); result = m_bInv ? Frac(rat) : Integer(rat);
break; break;
/* Return complement. */ /* Return complement. */
case IDC_COM: case IDC_COM:
result = rat.Not(m_fIntegerMode, m_chopNumbers[m_numwidth], m_radix, m_precision); if (m_radix == 10 && !m_fIntegerMode)
{
result = -(RationalMath::Integer(rat) + 1);
}
else
{
result = rat ^ m_chopNumbers[m_numwidth];
}
break; break;
// Rotate Left with hi bit wrapped over to lo bit // Rotate Left with hi bit wrapped over to lo bit
case IDC_ROL: case IDC_ROL:
if (m_fIntegerMode) if (m_fIntegerMode)
{ {
result = Integer(rat, m_radix, m_precision); result = Integer(rat);
uint64_t w64Bits = result.ToUInt64_t(m_radix, m_precision); uint64_t w64Bits = result.ToUInt64_t();
uint64_t msb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; uint64_t msb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
w64Bits <<= 1; // LShift by 1 w64Bits <<= 1; // LShift by 1
w64Bits |= msb; // Set the prev Msb as the current Lsb w64Bits |= msb; // Set the prev Msb as the current Lsb
result = Rational{ w64Bits, m_radix, m_precision }; result = w64Bits;
} }
break; break;
@ -59,14 +66,14 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
case IDC_ROR: case IDC_ROR:
if (m_fIntegerMode) if (m_fIntegerMode)
{ {
result = Integer(rat, m_radix, m_precision); result = Integer(rat);
uint64_t w64Bits = result.ToUInt64_t(m_radix, m_precision); 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 = Rational{ w64Bits, m_radix, m_precision }; result = w64Bits;
} }
break; break;
@ -76,12 +83,11 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
// Otherwise, we evaluate it as "X [op] (X * Y%)" // Otherwise, we evaluate it as "X [op] (X * Y%)"
if (m_nOpCode == IDC_MUL || m_nOpCode == IDC_DIV) if (m_nOpCode == IDC_MUL || m_nOpCode == IDC_DIV)
{ {
result = rat.Div(100, m_precision); result = rat / 100;
} }
else else
{ {
result = m_lastVal.Div(100, m_precision); result = rat * (m_lastVal / 100);
result = rat.Mul(result, m_precision);
} }
break; break;
} }
@ -89,76 +95,76 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
case IDC_SIN: /* Sine; normal and arc */ case IDC_SIN: /* Sine; normal and arc */
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
result = m_bInv ? ASin(rat, m_angletype, m_radix, m_precision) : Sin(rat, m_angletype, m_radix, m_precision); result = m_bInv ? ASin(rat, m_angletype) : Sin(rat, m_angletype);
} }
break; break;
case IDC_SINH: /* Sine- hyperbolic and archyperbolic */ case IDC_SINH: /* Sine- hyperbolic and archyperbolic */
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
result = m_bInv ? ASinh(rat, m_radix, m_precision) : Sinh(rat, m_radix, m_precision); result = m_bInv ? ASinh(rat) : Sinh(rat);
} }
break; break;
case IDC_COS: /* Cosine, follows convention of sine function. */ case IDC_COS: /* Cosine, follows convention of sine function. */
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
result = m_bInv ? ACos(rat, m_angletype, m_radix, m_precision) : Cos(rat, m_angletype, m_radix, m_precision); result = m_bInv ? ACos(rat, m_angletype) : Cos(rat, m_angletype);
} }
break; break;
case IDC_COSH: /* Cosine hyperbolic, follows convention of sine h function. */ case IDC_COSH: /* Cosine hyperbolic, follows convention of sine h function. */
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
result = m_bInv ? ACosh(rat, m_radix, m_precision) : Cosh(rat, m_radix, m_precision); result = m_bInv ? ACosh(rat) : Cosh(rat);
} }
break; break;
case IDC_TAN: /* Same as sine and cosine. */ case IDC_TAN: /* Same as sine and cosine. */
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
result = m_bInv ? ATan(rat, m_angletype, m_radix, m_precision) : Tan(rat, m_angletype, m_radix, m_precision); result = m_bInv ? ATan(rat, m_angletype) : Tan(rat, m_angletype);
} }
break; break;
case IDC_TANH: /* Same as sine h and cosine h. */ case IDC_TANH: /* Same as sine h and cosine h. */
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
result = m_bInv ? ATanh(rat, m_precision) : Tanh(rat, m_radix, m_precision); result = m_bInv ? ATanh(rat) : Tanh(rat);
} }
break; break;
case IDC_REC: /* Reciprocal. */ case IDC_REC: /* Reciprocal. */
result = Invert(rat, m_precision); result = Invert(rat);
break; break;
case IDC_SQR: /* Square */ case IDC_SQR: /* Square */
result = Pow(rat, 2, m_radix, m_precision); result = Pow(rat, 2);
break; break;
case IDC_SQRT: /* Square Root */ case IDC_SQRT: /* Square Root */
result = Root(rat, 2, m_radix, m_precision); result = Root(rat, 2);
break; break;
case IDC_CUBEROOT: case IDC_CUBEROOT:
case IDC_CUB: /* Cubing and cube root functions. */ case IDC_CUB: /* Cubing and cube root functions. */
result = IDC_CUBEROOT == op ? Root(rat, 3, m_radix, m_precision) : Pow(rat, 3, m_radix, m_precision); result = IDC_CUBEROOT == op ? Root(rat, 3) : Pow(rat, 3);
break; break;
case IDC_LOG: /* Functions for common log. */ case IDC_LOG: /* Functions for common log. */
result = Log10(rat, m_precision); result = Log10(rat);
break; break;
case IDC_POW10: case IDC_POW10:
result = Pow(10, rat, m_radix, m_precision); result = Pow(10, rat);
break; break;
case IDC_LN: /* Functions for natural log. */ case IDC_LN: /* Functions for natural log. */
result = m_bInv ? Exp(rat, m_radix, m_precision) : Log(rat, m_precision); result = m_bInv ? Exp(rat) : Log(rat);
break; break;
case IDC_FAC: /* Calculate factorial. Inverse is ineffective. */ case IDC_FAC: /* Calculate factorial. Inverse is ineffective. */
result = Fact(rat, m_radix, m_precision); result = Fact(rat);
break; break;
case IDC_DEGREES: case IDC_DEGREES:
@ -171,31 +177,28 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
{ {
if (!m_fIntegerMode) if (!m_fIntegerMode)
{ {
Rational shftRat{ m_bInv ? 100 : 60 }; auto shftRat{ m_bInv ? 100 : 60 };
Rational degreeRat = Integer(rat, m_radix, m_precision); Rational degreeRat = Integer(rat);
Rational minuteRat = rat.Sub(degreeRat, m_precision); Rational minuteRat = (rat - degreeRat) * shftRat;
minuteRat = minuteRat.Mul(shftRat, m_precision);
Rational secondRat = minuteRat; Rational secondRat = minuteRat;
minuteRat = Integer(minuteRat, m_radix, m_precision); minuteRat = Integer(minuteRat);
secondRat = secondRat.Sub(minuteRat, m_precision); secondRat = (secondRat - minuteRat) * shftRat;
secondRat = secondRat.Mul(shftRat, m_precision);
// //
// degreeRat == degrees, minuteRat == minutes, secondRat == seconds // degreeRat == degrees, minuteRat == minutes, secondRat == seconds
// //
shftRat = Rational{ m_bInv ? 60 : 100 }; shftRat = m_bInv ? 60 : 100;
secondRat = secondRat.Div(shftRat, m_precision); secondRat /= shftRat;
minuteRat = minuteRat.Add(secondRat, m_precision); minuteRat = (minuteRat + secondRat) / shftRat;
minuteRat = minuteRat.Div(shftRat, m_precision);
result = degreeRat.Add(minuteRat, m_precision); result = degreeRat + minuteRat;
} }
break; break;
} }

View file

@ -11,69 +11,68 @@ using namespace CalcEngine::RationalMath;
CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs) CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs)
{ {
// Remove any variance in how 0 could be represented in rat e.g. -0, 0/n, etc. // Remove any variance in how 0 could be represented in rat e.g. -0, 0/n, etc.
auto result = (!lhs.IsZero() ? lhs : Rational{}); auto result = (lhs != 0 ? lhs : 0);
try try
{ {
switch (operation) switch (operation)
{ {
case IDC_AND: case IDC_AND:
result = result.And(rhs, m_radix, m_precision); result &= rhs;
break; break;
case IDC_OR: case IDC_OR:
result = result.Or(rhs, m_radix, m_precision); result |= rhs;
break; break;
case IDC_XOR: case IDC_XOR:
result = result.Xor(rhs, m_radix, m_precision); result ^= rhs;
break; break;
case IDC_RSHF: case IDC_RSHF:
{ {
if (m_fIntegerMode && result.IsGreaterEq(Rational{ m_dwWordBitWidth }, m_precision)) // Lsh/Rsh >= than current word size is always 0 if (m_fIntegerMode && result >= m_dwWordBitWidth) // Lsh/Rsh >= than current word size is always 0
{ {
throw CALC_E_NORESULT; throw CALC_E_NORESULT;
} }
uint64_t w64Bits = rhs.ToUInt64_t(m_radix, m_precision); uint64_t w64Bits = rhs.ToUInt64_t();
bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
Rational holdVal = result; Rational holdVal = result;
result = rhs.Rsh(holdVal, m_radix, m_precision); result = rhs >> holdVal;
if (fMsb) if (fMsb)
{ {
result = Integer(result, m_radix, m_precision); result = Integer(result);
auto tempRat = m_chopNumbers[m_numwidth].Rsh(holdVal, m_radix, m_precision); auto tempRat = m_chopNumbers[m_numwidth] >> holdVal;
tempRat = Integer(tempRat, m_radix, m_precision); tempRat = Integer(tempRat);
tempRat = tempRat.Xor(m_chopNumbers[m_numwidth], m_radix, m_precision); result |= tempRat ^ m_chopNumbers[m_numwidth];
result = result.Or(tempRat, m_radix, m_precision);
} }
break; break;
} }
case IDC_LSHF: case IDC_LSHF:
if (m_fIntegerMode && result.IsGreaterEq(Rational{ m_dwWordBitWidth }, m_precision)) // Lsh/Rsh >= than current word size is always 0 if (m_fIntegerMode && result >= m_dwWordBitWidth) // Lsh/Rsh >= than current word size is always 0
{ {
throw CALC_E_NORESULT; throw CALC_E_NORESULT;
} }
result = rhs.Lsh(result, m_radix, m_precision); result = rhs << result;
break; break;
case IDC_ADD: case IDC_ADD:
result = result.Add(rhs, m_precision); result += rhs;
break; break;
case IDC_SUB: case IDC_SUB:
result = rhs.Sub(result, m_precision); result = rhs - result;
break; break;
case IDC_MUL: case IDC_MUL:
result = result.Mul(rhs, m_precision); result *= rhs;
break; break;
case IDC_DIV: case IDC_DIV:
@ -85,24 +84,22 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
if (m_fIntegerMode) if (m_fIntegerMode)
{ {
uint64_t w64Bits = rhs.ToUInt64_t(m_radix, m_precision); uint64_t w64Bits = rhs.ToUInt64_t();
bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
if (fMsb) if (fMsb)
{ {
result = rhs.Not(true /* IntegerMode */, m_chopNumbers[m_numwidth], m_radix, m_precision); result = (rhs ^ m_chopNumbers[m_numwidth]) + 1;
result = result.Add(1, m_precision);
iNumeratorSign = -1; iNumeratorSign = -1;
} }
w64Bits = temp.ToUInt64_t(m_radix, m_precision); w64Bits = temp.ToUInt64_t();
fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1;
if (fMsb) if (fMsb)
{ {
temp = temp.Not(true /* IntegerMode */, m_chopNumbers[m_numwidth], m_radix, m_precision); temp = (temp ^ m_chopNumbers[m_numwidth]) + 1;
temp = temp.Add(1, m_precision);
iDenominatorSign = -1; iDenominatorSign = -1;
} }
@ -111,28 +108,28 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
if (operation == IDC_DIV) if (operation == IDC_DIV)
{ {
iFinalSign = iNumeratorSign * iDenominatorSign; iFinalSign = iNumeratorSign * iDenominatorSign;
result = result.Div(temp, m_precision); result /= temp;
} }
else else
{ {
iFinalSign = iNumeratorSign; iFinalSign = iNumeratorSign;
result = result.Mod(temp); result %= temp;
} }
if (m_fIntegerMode && iFinalSign == -1) if (m_fIntegerMode && iFinalSign == -1)
{ {
result = Integer(result, m_radix, m_precision).Negate(); result = -(Integer(result));
} }
break; break;
} }
case IDC_PWR: // Calculates rhs to the result(th) power. case IDC_PWR: // Calculates rhs to the result(th) power.
result = Pow(rhs, result, m_radix, m_precision); result = Pow(rhs, result);
break; break;
case IDC_ROOT: // Calculates rhs to the result(th) root. case IDC_ROOT: // Calculates rhs to the result(th) root.
result = Root(rhs, result, m_radix, m_precision); result = Root(rhs, result);
break; break;
} }
} }

View file

@ -13,21 +13,20 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwid
{ {
// 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 propogated. 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)
{ {
uint64_t w64Bits = m_currentVal.ToUInt64_t(m_radix, m_precision); uint64_t w64Bits = m_currentVal.ToUInt64_t();
bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; // make sure you use the old width bool fMsb = (w64Bits >> (m_dwWordBitWidth - 1)) & 1; // make sure you use the old width
if (fMsb) if (fMsb)
{ {
// If high bit is set, then get the decimal number in -ve 2'scompl form. // If high bit is set, then get the decimal number in -ve 2'scompl form.
auto tempResult = m_currentVal.Not(true /* IntegerMode */, m_chopNumbers[m_numwidth], m_radix, m_precision); auto tempResult = m_currentVal ^ m_chopNumbers[m_numwidth];
tempResult = tempResult.Add(1, m_precision);
m_currentVal = tempResult.Negate(); m_currentVal = -(tempResult + 1);
} }
} }
@ -43,7 +42,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwid
m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(numwidth); m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(numwidth);
} }
// inform ratpak that a change in base or precision has occured // 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
@ -85,16 +84,13 @@ bool CCalcEngine::TryToggleBit(CalcEngine::Rational& rat, DWORD wbitno)
return false; // ignore error cant happen return false; // ignore error cant happen
} }
Rational result = Integer(rat, m_radix, m_precision); Rational result = Integer(rat);
if (result.IsZero())
{
// This is the same work around happenning in SciCalcFunctions. Ought to move to intrat function itself.
// Basic bug is there which doesn't treat 0/ n as 0, or -0 as 0 etc.
result = Rational{};
}
auto pow = Pow(2, static_cast<int32_t>(wbitno), m_radix, m_precision); // Remove any variance in how 0 could be represented in rat e.g. -0, 0/n, etc.
rat = result.Xor(pow, m_radix, m_precision); result = (result != 0 ? result : 0);
// XOR the result with 2^wbitno power
rat = result ^ Pow(2, static_cast<int32_t>(wbitno));
return true; return true;
} }
@ -134,8 +130,8 @@ int CCalcEngine::QuickLog2(int iNum)
// word size, and base. This number is conservative towards the small side // word size, and base. This number is conservative towards the small side
// such that there may be some extra bits left over. For example, base 8 requires 3 bits per digit. // such that there may be some extra bits left over. For example, base 8 requires 3 bits per digit.
// A word size of 32 bits allows for 10 digits with a remainder of two bits. Bases // A word size of 32 bits allows for 10 digits with a remainder of two bits. Bases
// that require variable numnber of bits (non-power-of-two bases) are approximated // that require variable number of bits (non-power-of-two bases) are approximated
// by the next highest power-of-two base (again, to be conservative and gaurentee // by the next highest power-of-two base (again, to be conservative and guarantee
// there will be no over flow verse the current word size for numbers entered). // there will be no over flow verse the current word size for numbers entered).
// Base 10 is a special case and always uses the base 10 precision (m_nPrecisionSav). // Base 10 is a special case and always uses the base 10 precision (m_nPrecisionSav).
void CCalcEngine::UpdateMaxIntDigits() void CCalcEngine::UpdateMaxIntDigits()
@ -164,10 +160,10 @@ void CCalcEngine::ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t
{ {
if (10 == radix) if (10 == radix)
{ {
ChangeConstants(radix, precision); // Base 10 precesion 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 preceisly. 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 doesnt 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 otherwords 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

@ -281,7 +281,7 @@
<ClInclude Include="Header Files\Number.h" /> <ClInclude Include="Header Files\Number.h" />
<ClInclude Include="Header Files\RadixType.h" /> <ClInclude Include="Header Files\RadixType.h" />
<ClInclude Include="Header Files\Rational.h" /> <ClInclude Include="Header Files\Rational.h" />
<ClInclude Include="Header Files\scimath.h" /> <ClInclude Include="Header Files\RationalMath.h" />
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="Ratpack\CalcErr.h" /> <ClInclude Include="Ratpack\CalcErr.h" />
<ClInclude Include="Ratpack\ratconst.h" /> <ClInclude Include="Ratpack\ratconst.h" />
@ -300,7 +300,7 @@
<ClCompile Include="CEngine\scicomm.cpp" /> <ClCompile Include="CEngine\scicomm.cpp" />
<ClCompile Include="CEngine\scidisp.cpp" /> <ClCompile Include="CEngine\scidisp.cpp" />
<ClCompile Include="CEngine\scifunc.cpp" /> <ClCompile Include="CEngine\scifunc.cpp" />
<ClCompile Include="CEngine\scimath.cpp" /> <ClCompile Include="CEngine\RationalMath.cpp" />
<ClCompile Include="CEngine\scioper.cpp" /> <ClCompile Include="CEngine\scioper.cpp" />
<ClCompile Include="CEngine\sciset.cpp" /> <ClCompile Include="CEngine\sciset.cpp" />
<ClCompile Include="ExpressionCommand.cpp" /> <ClCompile Include="ExpressionCommand.cpp" />

View file

@ -32,9 +32,6 @@
<ClCompile Include="CEngine\scifunc.cpp"> <ClCompile Include="CEngine\scifunc.cpp">
<Filter>CEngine</Filter> <Filter>CEngine</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="CEngine\scimath.cpp">
<Filter>CEngine</Filter>
</ClCompile>
<ClCompile Include="CEngine\scioper.cpp"> <ClCompile Include="CEngine\scioper.cpp">
<Filter>CEngine</Filter> <Filter>CEngine</Filter>
</ClCompile> </ClCompile>
@ -89,6 +86,9 @@
<ClCompile Include="CEngine\Rational.cpp"> <ClCompile Include="CEngine\Rational.cpp">
<Filter>CEngine</Filter> <Filter>CEngine</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="CEngine\RationalMath.cpp">
<Filter>CEngine</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Command.h" /> <ClInclude Include="Command.h" />
@ -110,9 +110,6 @@
<ClInclude Include="Header Files\EngineStrings.h"> <ClInclude Include="Header Files\EngineStrings.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Header Files\scimath.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Ratpack\CalcErr.h"> <ClInclude Include="Ratpack\CalcErr.h">
<Filter>RatPack</Filter> <Filter>RatPack</Filter>
</ClInclude> </ClInclude>
@ -164,5 +161,8 @@
<ClInclude Include="Header Files\RadixType.h"> <ClInclude Include="Header Files\RadixType.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Header Files\RationalMath.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -600,8 +600,8 @@ namespace CalculationManager
} }
/// <summary> /// <summary>
/// Helper function that selects a memeory from the vector and set it to CCalcEngine /// Helper function that selects a memory from the vector and set it to CCalcEngine
/// Saved RAT number needs to be copied and passed in, as CCalcEngine destoried the passed in RAT /// Saved RAT number needs to be copied and passed in, as CCalcEngine destroyed the passed in RAT
/// </summary> /// </summary>
/// <param name="indexOfMemeory">Index of the target memory</param> /// <param name="indexOfMemeory">Index of the target memory</param>
void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberSelect(_In_ unsigned int indexOfMemory)
@ -615,7 +615,7 @@ namespace CalculationManager
/// <summary> /// <summary>
/// Helper function that needs to be executed when memory is modified /// Helper function that needs to be executed when memory is modified
/// When memory is modified, destory the old RAT and put the new RAT in vector /// When memory is modified, destroy the old RAT and put the new RAT in vector
/// </summary> /// </summary>
/// <param name="indexOfMemeory">Index of the target memory</param> /// <param name="indexOfMemeory">Index of the target memory</param>
void CalculatorManager::MemorizedNumberChanged(_In_ unsigned int indexOfMemory) void CalculatorManager::MemorizedNumberChanged(_In_ unsigned int indexOfMemory)

View file

@ -60,7 +60,7 @@ namespace CalculationManager
static const unsigned int m_maximumMemorySize = 100; static const unsigned int m_maximumMemorySize = 100;
// For persistance // For persistence
std::vector<unsigned char> m_savedCommands; std::vector<unsigned char> m_savedCommands;
std::vector<long> m_savedPrimaryValue; std::vector<long> m_savedPrimaryValue;
std::vector<long> m_serializedMemory; std::vector<long> m_serializedMemory;

View file

@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
/****************************Module*Header*********************************** /****************************Module*Header***********************************
* Module Name: CCommand.h * Module Name: CCommand.h
* *
* Module Descripton: * Module Description:
* Resource ID's for the Engine Commands exposed. * Resource ID's for the Engine Commands exposed.
* *
* Warnings: * Warnings:

View file

@ -5,7 +5,7 @@
/****************************Module*Header***********************************\ /****************************Module*Header***********************************\
* Module Name: CalcEngine.h * Module Name: CalcEngine.h
* *
* Module Descripton: * Module Description:
* The class definition for the Calculator's engine class CCalcEngine * The class definition for the Calculator's engine class CCalcEngine
* *
* Warnings: * Warnings:
@ -14,7 +14,6 @@
* *
\****************************************************************************/ \****************************************************************************/
#include "scimath.h"
#include "CCommand.h" #include "CCommand.h"
#include "EngineStrings.h" #include "EngineStrings.h"
#include "../Command.h" #include "../Command.h"
@ -25,6 +24,7 @@
#include "CalcInput.h" #include "CalcInput.h"
#include "ICalcDisplay.h" #include "ICalcDisplay.h"
#include "Rational.h" #include "Rational.h"
#include "RationalMath.h"
// The following are NOT real exports of CalcEngine, but for forward declarations // The following are NOT real exports of CalcEngine, but for forward declarations
// The real exports follows later // The real exports follows later
@ -69,7 +69,7 @@ public:
wchar_t DecimalSeparator() const; wchar_t DecimalSeparator() const;
// Static methods for the instance // Static methods for the instance
static void InitialOneTimeOnlySetup(CalculationManager::IResourceProvider& resourceProvider); // Once per load time to call to intialize all shared global variables static void InitialOneTimeOnlySetup(CalculationManager::IResourceProvider& resourceProvider); // Once per load time to call to initialize all shared global variables
// returns the ptr to string representing the operator. Mostly same as the button, but few special cases for x^y etc. // returns the ptr to string representing the operator. Mostly same as the button, but few special cases for x^y etc.
static std::wstring_view GetString(int ids) { return s_engineStrings[ids]; } static std::wstring_view GetString(int ids) { return s_engineStrings[ids]; }
static std::wstring_view OpCodeToString(int nOpCode) { return GetString(IdStrFromCmdId(nOpCode)); } static std::wstring_view OpCodeToString(int nOpCode) { return GetString(IdStrFromCmdId(nOpCode)); }
@ -82,10 +82,10 @@ private:
CalculationManager::IResourceProvider* const m_resourceProvider; CalculationManager::IResourceProvider* const m_resourceProvider;
int m_nOpCode; /* ID value of operation. */ int m_nOpCode; /* ID value of operation. */
int m_nPrevOpCode; // opcode which computed the number in m_currentVal. 0 if it is already bracketed or plain number or int m_nPrevOpCode; // opcode which computed the number in m_currentVal. 0 if it is already bracketed or plain number or
// if it hasnt 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; //Falg for setting teh 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;
@ -112,7 +112,7 @@ private:
int m_openParenCount; // Number of open parentheses. int m_openParenCount; // Number of open parentheses.
std::array<int, MAXPRECDEPTH> m_nOp; /* Holding array for parenthesis operations. */ std::array<int, MAXPRECDEPTH> m_nOp; /* Holding array for parenthesis operations. */
std::array<int, MAXPRECDEPTH> m_nPrecOp; /* Holding array for precedence operations. */ std::array<int, MAXPRECDEPTH> m_nPrecOp; /* Holding array for precedence operations. */
int m_nPrecNum; /* Current number of precedence ops in holding. */ size_t m_precedenceOpCount; /* Current number of precedence ops in holding. */
int m_nLastCom; // Last command entered. int m_nLastCom; // Last command entered.
ANGLE_TYPE m_angletype; // Current Angle type when in dec mode. one of deg, rad or grad ANGLE_TYPE m_angletype; // Current Angle type when in dec mode. one of deg, rad or grad
NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode. NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode.

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
@ -6,8 +6,8 @@
bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y); bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y);
bool IsBinOpCode(WPARAM opCode); bool IsBinOpCode(WPARAM opCode);
// WARNING: IDC_SIGN is a special unary op but still this doesnt catch this. Caller has to be aware // WARNING: IDC_SIGN is a special unary op but still this doesn't catch this. Caller has to be aware
// of it and catch it themself or not needing this // of it and catch it themselves or not needing this
bool IsUnaryOpCode(WPARAM opCode); bool IsUnaryOpCode(WPARAM opCode);
bool IsDigitOpCode(WPARAM opCode); bool IsDigitOpCode(WPARAM opCode);
bool IsGuiSettingOpCode(WPARAM opCode); bool IsGuiSettingOpCode(WPARAM opCode);

View file

@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
/****************************Module*Header*********************************** /****************************Module*Header***********************************
* Module Name: EngineStrings.h * Module Name: EngineStrings.h
* *
* Module Descripton: * Module Description:
* Resource String ID's for the private strings used by Engine. Internal to Engine related code * Resource String ID's for the private strings used by Engine. Internal to Engine related code
* not required by the clients * not required by the clients
* *

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
@ -11,7 +11,7 @@
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 seperate 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:
@ -38,7 +38,7 @@ private:
std::shared_ptr<IHistoryDisplay> m_pHistoryDisplay; std::shared_ptr<IHistoryDisplay> m_pHistoryDisplay;
ICalcDisplay *m_pCalcDisplay; ICalcDisplay *m_pCalcDisplay;
int m_iCurLineHistStart; // index of the begginning 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

View file

@ -1,4 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once #pragma once

View file

@ -1,4 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once #pragma once
@ -6,6 +7,13 @@
namespace CalcEngine namespace CalcEngine
{ {
// Default Base/Radix to use for Rational calculations
// RatPack calculations currently support up to Base64.
inline constexpr uint32_t RATIONAL_BASE = 10;
// Default Precision to use for Rational calculations
inline constexpr int32_t RATIONAL_PRECISION = 128;
class Rational class Rational
{ {
public: public:
@ -14,7 +22,7 @@ namespace CalcEngine
Rational(Number const& p, Number const& q) noexcept; Rational(Number const& p, Number const& q) noexcept;
Rational(int32_t i); Rational(int32_t i);
Rational(uint32_t ui); Rational(uint32_t ui);
Rational(uint64_t ui, uint32_t radix, int32_t precision); Rational(uint64_t ui);
explicit Rational(PRAT prat) noexcept; explicit Rational(PRAT prat) noexcept;
PRAT ToPRAT() const; PRAT ToPRAT() const;
@ -22,29 +30,42 @@ namespace CalcEngine
Number const& P() const; Number const& P() const;
Number const& Q() const; Number const& Q() const;
Rational Negate() const; Rational operator-() const;
Rational Add(Rational const& rhs, int32_t precision) const; Rational& operator+=(Rational const& rhs);
Rational Sub(Rational const& rhs, int32_t precision) const; Rational& operator-=(Rational const& rhs);
Rational Mul(Rational const& rhs, int32_t precision) const; Rational& operator*=(Rational const& rhs);
Rational Div(Rational const& rhs, int32_t precision) const; Rational& operator/=(Rational const& rhs);
Rational Mod(Rational const& rhs) const; Rational& operator%=(Rational const& rhs);
Rational Lsh(Rational const& r, uint32_t radix, int32_t precision) const; Rational& operator<<=(Rational const& rhs);
Rational Rsh(Rational const& r, uint32_t radix, int32_t precision) const; Rational& operator>>=(Rational const& rhs);
Rational Not(bool isIntegerMode, Rational const& chopNum, uint32_t radix, int32_t precision) const; Rational& operator&=(Rational const& rhs);
Rational And(Rational const& r, uint32_t radix, int32_t precision) const; Rational& operator|=(Rational const& rhs);
Rational Or(Rational const& r, uint32_t radix, int32_t precision) const; Rational& operator^=(Rational const& rhs);
Rational Xor(Rational const& r, uint32_t radix, int32_t precision) const;
bool IsZero() const; friend Rational operator+(Rational lhs, Rational const& rhs);
bool IsLess(Rational const& r, int32_t precision) const; friend Rational operator-(Rational lhs, Rational const& rhs);
bool IsLessEq(Rational const& r, int32_t precision) const; friend Rational operator*(Rational lhs, Rational const& rhs);
bool IsGreaterEq(Rational const& r, int32_t precision) const; friend Rational operator/(Rational lhs, Rational const& rhs);
bool IsEq(Rational const& r, int32_t precision) const; friend Rational operator%(Rational lhs, Rational const& rhs);
friend Rational operator<<(Rational lhs, Rational const& rhs);
friend Rational operator>>(Rational lhs, Rational const& rhs);
friend Rational operator&(Rational lhs, Rational const& rhs);
friend Rational operator|(Rational lhs, Rational const& rhs);
friend Rational operator^(Rational lhs, Rational const& rhs);
friend bool operator==(Rational const& lhs, Rational const& rhs);
friend bool operator!=(Rational const& lhs, Rational const& rhs);
friend bool operator<(Rational const& lhs, Rational const& rhs);
friend bool operator>(Rational const& lhs, Rational const& rhs);
friend bool operator<=(Rational const& lhs, Rational const& rhs);
friend bool operator>=(Rational const& lhs, Rational const& rhs);
std::wstring ToString(uint32_t radix, NUMOBJ_FMT format, int32_t precision) const; std::wstring ToString(uint32_t radix, NUMOBJ_FMT format, int32_t precision) const;
uint64_t ToUInt64_t(uint32_t radix, int32_t precision) const; uint64_t ToUInt64_t() const;
private: private:
Number m_p; Number m_p;

View file

@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Rational.h"
namespace CalcEngine::RationalMath
{
Rational Frac(Rational const& rat);
Rational Integer(Rational const& rat);
Rational Pow(Rational const& base, Rational const& pow);
Rational Root(Rational const& base, Rational const& root);
Rational Fact(Rational const& rat);
Rational Exp(Rational const& rat);
Rational Log(Rational const& rat);
Rational Log10(Rational const& rat);
Rational Invert(Rational const& rat);
Rational Abs(Rational const& rat);
Rational Sin(Rational const& rat, ANGLE_TYPE angletype);
Rational Cos(Rational const& rat, ANGLE_TYPE angletype);
Rational Tan(Rational const& rat, ANGLE_TYPE angletype);
Rational ASin(Rational const& rat, ANGLE_TYPE angletype);
Rational ACos(Rational const& rat, ANGLE_TYPE angletype);
Rational ATan(Rational const& rat, ANGLE_TYPE angletype);
Rational Sinh(Rational const& rat);
Rational Cosh(Rational const& rat);
Rational Tanh(Rational const& rat);
Rational ASinh(Rational const& rat);
Rational ACosh(Rational const& rat);
Rational ATanh(Rational const& rat);
}

View file

@ -1,35 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "Rational.h"
namespace CalcEngine::RationalMath
{
Rational Frac(Rational const& rat, uint32_t radix, int32_t precision);
Rational Integer(Rational const& rat, uint32_t radix, int32_t precision);
Rational Pow(Rational const& base, Rational const& pow, uint32_t radix, int32_t precision);
Rational Root(Rational const& base, Rational const& root, uint32_t radix, int32_t precision);
Rational Fact(Rational const& rat, uint32_t radix, int32_t precision);
Rational Exp(Rational const& rat, uint32_t radix, int32_t precision);
Rational Log(Rational const& rat, int32_t precision);
Rational Log10(Rational const& rat, int32_t precision);
Rational Invert(Rational const& rat, int32_t precision);
Rational Abs(Rational const& rat);
Rational Sin(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
Rational Cos(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
Rational Tan(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
Rational ASin(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
Rational ACos(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
Rational ATan(Rational const& rat, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
Rational Sinh(Rational const& rat, uint32_t radix, int32_t precision);
Rational Cosh(Rational const& rat, uint32_t radix, int32_t precision);
Rational Tanh(Rational const& rat, uint32_t radix, int32_t precision);
Rational ASinh(Rational const& rat, uint32_t radix, int32_t precision);
Rational ACosh(Rational const& rat, uint32_t radix, int32_t precision);
Rational ATanh(Rational const& rat, int32_t precision);
}

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.
// CalcErr.h // CalcErr.h
@ -6,7 +6,7 @@
// Defines the error codes thrown by ratpak and caught by Calculator // Defines the error codes thrown by ratpak and caught by Calculator
// //
// //
// Ratpak errors are 32 bit values layed out as follows: // Ratpak errors are 32 bit values laid out as follows:
// //
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
@ -31,8 +31,8 @@
// //
// Code - is the actual error code // Code - is the actual error code
// //
// This format is based losely on an OLE HRESULT and is compatible with the // This format is based loosely on an OLE HRESULT and is compatible with the
// SUCCEEDED and FAILED marcos as well as the HRESULT_CODE macro // SUCCEEDED and FAILED macros as well as the HRESULT_CODE macro
// CALC_E_DIVIDEBYZERO // CALC_E_DIVIDEBYZERO
// //

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.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -42,7 +42,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 nonone. // pa and b are both non-one.
_mulnumx( pa, b ); _mulnumx( pa, b );
} }
else else
@ -71,7 +71,7 @@ void __inline mulnumx( PNUMBER *pa, PNUMBER b )
// //
// DESCRIPTION: Does the number equivalent of *pa *= b. // DESCRIPTION: Does the number equivalent of *pa *= b.
// Assumes the base is BASEX of both numbers. This algorithm is the // Assumes the base is BASEX of both numbers. This algorithm is the
// same one you learned in gradeschool, except the base isn't 10 it's // same one you learned in grade school, except the base isn't 10 it's
// BASEX. // BASEX.
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -148,7 +148,7 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
} }
} }
// prevent different kinds of zeros, by stripping leading duplicate zeroes. // 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 )
{ {
@ -342,7 +342,7 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
if ( !cdigits ) if ( !cdigits )
{ {
// A zero, make sure no wierd exponents creep in // A zero, make sure no weird exponents creep in
c->exp = 0; c->exp = 0;
c->cdigit = 1; c->cdigit = 1;
} }
@ -351,7 +351,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
// zeroes. 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 )
{ {
c->cdigit--; c->cdigit--;

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.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -33,7 +33,7 @@ long g_ratio; // int(log(2L^BASEXPWR)/log(radix))
// Default decimal separator // Default decimal separator
wchar_t g_decimalSeparator = L'.'; wchar_t g_decimalSeparator = L'.';
// Used to strip trailing zeroes, and prevent combinatorial explosions // Used to strip trailing zeros, and prevent combinatorial explosions
bool stripzeroesnum(_Inout_ PNUMBER pnum, long starting); bool stripzeroesnum(_Inout_ PNUMBER pnum, long starting);
void SetDecimalSeparator(wchar_t decimalSeparator) void SetDecimalSeparator(wchar_t decimalSeparator)
@ -121,7 +121,7 @@ void _destroyrat( _In_ PRAT prat )
// //
// RETURN: pointer to a number // RETURN: pointer to a number
// //
// DESCRIPTION: allocates and zeroes out number type. // DESCRIPTION: allocates and zeros out number type.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -347,6 +347,7 @@ PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix)
// mantissa a string representation of a number // mantissa a string representation of a number
// exponentIsNegative true if exponent is less than zero // exponentIsNegative true if exponent is less than zero
// exponent a string representation of a number // exponent a string representation of a number
// radix is the number base used in the source string
// //
// RETURN: PRAT representation of string input. // RETURN: PRAT representation of string input.
// Or nullptr if no number scanned. // Or nullptr if no number scanned.
@ -479,7 +480,7 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs
// ZR '0' // ZR '0'
// NZ '1'..'9' 'A'..'Z' 'a'..'z' '@' '_' // NZ '1'..'9' 'A'..'Z' 'a'..'z' '@' '_'
// SG '+' '-' // SG '+' '-'
// EX 'e' '^' e is used for radix 10, ^ for all other radixs. // EX 'e' '^' e is used for radix 10, ^ for all other radixes.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static constexpr uint8_t DP = 0; static constexpr uint8_t DP = 0;
@ -910,8 +911,8 @@ unsigned long rattoUlong( _In_ PRAT prat, uint32_t radix, int32_t precision)
// DESCRIPTION: returns the 64 bit (irrespective of which processor this is running in) representation of the // DESCRIPTION: returns the 64 bit (irrespective of which processor this is running in) representation of the
// number input. Assumes that the number is in the internal // number input. Assumes that the number is in the internal
// base. Can throw exception if the number exceeds 2^64 // base. Can throw exception if the number exceeds 2^64
// Implementation by getting the HI & LO 32 bit words and concating them, as the // Implementation by getting the HI & LO 32 bit words and concatenating them, as the
// internal base choosen happens to be 2^32, this is easier. // internal base chosen happens to be 2^32, this is easier.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ULONGLONG rattoUlonglong( _In_ PRAT prat, uint32_t radix, int32_t precision) ULONGLONG rattoUlonglong( _In_ PRAT prat, uint32_t radix, int32_t precision)
@ -980,7 +981,7 @@ long numtolong( _In_ PNUMBER pnum, uint32_t radix )
// //
// RETURN: true if stripping done, modifies number in place. // RETURN: true if stripping done, modifies number in place.
// //
// DESCRIPTION: Strips off trailing zeroes. // DESCRIPTION: Strips off trailing zeros.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1000,7 +1001,7 @@ bool stripzeroesnum(_Inout_ PNUMBER pnum, long starting)
cdigits = starting; cdigits = starting;
} }
// Check we haven't gone too far, and we are still looking at zeroes. // Check we haven't gone too far, and we are still looking at zeros.
while ( ( cdigits > 0 ) && !(*pmant) ) while ( ( cdigits > 0 ) && !(*pmant) )
{ {
// move to next significant digit and keep track of digits we can // move to next significant digit and keep track of digits we can
@ -1010,7 +1011,7 @@ bool stripzeroesnum(_Inout_ PNUMBER pnum, long starting)
fstrip = true; fstrip = true;
} }
// If there are zeroes to remove. // If there are zeros to remove.
if ( fstrip ) if ( fstrip )
{ {
// Remove them. // Remove them.
@ -1060,7 +1061,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
// 10 for maximum exponent size. // 10 for maximum exponent size.
int cchNum = (precision + 16); int cchNum = (precision + 16);
// If there is a chance a round has to occour, 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
PNUMBER round = nullptr; PNUMBER round = nullptr;
@ -1086,7 +1087,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
if (format == FMT_FLOAT) if (format == FMT_FLOAT)
{ {
// Figure out if the exponent will fill more space than the nonexponent field. // Figure out if the exponent will fill more space than the non-exponent field.
if ((length - exponent > precision) || (exponent > precision + 3)) if ((length - exponent > precision) || (exponent > precision + 3))
{ {
if (exponent >= -MAX_ZEROS_AFTER_DECIMAL) if (exponent >= -MAX_ZEROS_AFTER_DECIMAL)
@ -1096,15 +1097,15 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
} }
else else
{ {
// Case where too many zeroes are to the right or left of the // Case where too many zeros are to the right or left of the
// decimal pt. And we are forced to switch to scientific form. // decimal pt. And we are forced to switch to scientific form.
format = FMT_SCIENTIFIC; format = FMT_SCIENTIFIC;
} }
} }
else if (length + abs(exponent) < precision && round) else if (length + abs(exponent) < precision && round)
{ {
// Minimum loss of precision occours with listing leading zeros // Minimum loss of precision occurs with listing leading zeros
// if we need to make room for zeroes sacrifice some digits. // if we need to make room for zeros sacrifice some digits.
round->exp -= exponent; round->exp -= exponent;
} }
} }
@ -1117,7 +1118,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
if (stripzeroesnum(pnum, offset)) if (stripzeroesnum(pnum, offset))
{ {
// WARNING: nesting/recursion, too much has been changed, need to // WARNING: nesting/recursion, too much has been changed, need to
// refigure format. // re-figure format.
return NumberToString(pnum, oldFormat, radix, precision); return NumberToString(pnum, oldFormat, radix, precision);
} }
} }
@ -1164,7 +1165,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
// Begin building the result string // Begin building the result string
wstringstream resultStream{}; wstringstream resultStream{};
// Make sure negative zeroes aren't allowed. // Make sure negative zeros aren't allowed.
if ((pnum->sign == -1) && (length > 0)) if ((pnum->sign == -1) && (length > 0))
{ {
resultStream << L'-'; resultStream << L'-';
@ -1258,20 +1259,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision) wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision)
{ {
// Convert p and q of rational form from internal base to requested base. PNUMBER p = RatToNumber(prat, radix, precision);
// Scale by largest power of BASEX possible.
long scaleby = min(prat->pp->exp, prat->pq->exp);
scaleby = max(scaleby, 0);
prat->pp->exp -= scaleby;
prat->pq->exp -= scaleby;
PNUMBER p = nRadixxtonum(prat->pp, radix, precision);
PNUMBER q = nRadixxtonum(prat->pq, radix, precision);
// finally take the time hit to actually divide.
divnum(&p, q, radix, precision);
destroynum(q);
wstring result = NumberToString(p, format, radix, precision); wstring result = NumberToString(p, format, radix, precision);
destroynum(p); destroynum(p);
@ -1279,6 +1267,40 @@ wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t prec
return result; return result;
} }
PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision)
{
PRAT temprat = nullptr;
DUPRAT(temprat, prat);
// Convert p and q of rational form from internal base to requested base.
// Scale by largest power of BASEX possible.
long scaleby = min(temprat->pp->exp, temprat->pq->exp);
scaleby = max(scaleby, 0);
temprat->pp->exp -= scaleby;
temprat->pq->exp -= scaleby;
PNUMBER p = nRadixxtonum(temprat->pp, radix, precision);
PNUMBER q = nRadixxtonum(temprat->pq, radix, precision);
destroyrat(temprat);
// finally take the time hit to actually divide.
divnum(&p, q, radix, precision);
destroynum(q);
return p;
}
// Converts a PRAT to a PNUMBER and back to a PRAT, flattening/simplifying the rational in the process
void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision)
{
PNUMBER pnum = RatToNumber(prat, radix, precision);
destroyrat(prat);
prat = numtorat(pnum, radix);
destroynum(pnum);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// FUNCTION: gcd // FUNCTION: gcd
@ -1377,7 +1399,7 @@ PNUMBER longfactnum(long inlong, uint32_t radix)
// ARGUMENTS: // ARGUMENTS:
// long integer to factorialize. // long integer to factorialize.
// long integer representing base of answer. // long integer representing base of answer.
// unsignd long integer for radix // unsigned long integer for radix
// //
// RETURN: Factorial of input in base PNUMBER form. // RETURN: Factorial of input in base PNUMBER form.
// //

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.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -235,7 +235,7 @@ void log10rat( PRAT *px, int32_t precision)
} }
// //
// return if the given x is even number. The assumption here is its numberator is 1 and we are testing the numerator is // return if the given x is even number. The assumption here is its numerator 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)
{ {
@ -291,7 +291,7 @@ void powrat(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
catch (...) catch (...)
{ {
// If calculating the power using numerator/denominator // If calculating the power using numerator/denominator
// failed, fallback to the less accurate method of // failed, fall back to the less accurate method of
// passing in the original y // passing in the original y
powratcomp(px, y, radix, precision); powratcomp(px, y, radix, precision);
} }

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.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -150,7 +150,7 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
} }
else else
{ {
// In this particular case an overflow or underflow has occoured // 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.
@ -167,7 +167,7 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
} }
} }
// Remove leading zeroes, 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 )
{ {
@ -188,7 +188,7 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// //
// DESCRIPTION: Does the number equivalent of *pa *= b. // DESCRIPTION: Does the number equivalent of *pa *= b.
// Assumes radix is the radix of both numbers. This algorithm is the // Assumes radix is the radix of both numbers. This algorithm is the
// same one you learned in gradeschool. // same one you learned in grade school.
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -200,7 +200,7 @@ void __inline mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 ) if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 )
{ // If b is one we don't multiply exactly. { // If b is one we don't multiply exactly.
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 nonone. { // pa and b are both non-one.
_mulnum( pa, b, radix); _mulnum( pa, b, radix);
} }
else else
@ -285,7 +285,7 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
} }
} }
// prevent different kinds of zeros, by stripping leading duplicate zeroes. // 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 )
{ {

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.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -73,16 +73,11 @@ void gcdrat( PRAT *pa, uint32_t radix, int32_t precision)
void fracrat( PRAT *pa , uint32_t radix, int32_t precision) void fracrat( PRAT *pa , uint32_t radix, int32_t precision)
{ {
// Only do the intrat operation if number is nonzero. // Only do the flatrat operation if number is nonzero.
// and only if the bottom part is not one. // and only if the bottom part is not one.
if ( !zernum( (*pa)->pp ) && !equnum( (*pa)->pq, num_one ) ) if ( !zernum( (*pa)->pp ) && !equnum( (*pa)->pq, num_one ) )
{ {
wstring ratStr = RatToString(*pa, FMT_FLOAT, radix, precision); flatrat(*pa, radix, precision);
PNUMBER pnum = StringToNumber(ratStr, radix, precision);
destroyrat( *pa );
*pa = numtorat( pnum, radix);
destroynum( pnum );
} }
remnum( &((*pa)->pp), (*pa)->pq, BASEX ); remnum( &((*pa)->pp), (*pa)->pq, BASEX );
@ -242,7 +237,7 @@ void addrat( PRAT *pa, PRAT b, int32_t precision)
(*pa)->pq = bot; (*pa)->pq = bot;
trimit(pa, precision); trimit(pa, precision);
// Get rid of negative zeroes 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;
} }

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
@ -316,6 +316,10 @@ extern std::wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t r
// returns a text representation of a PRAT // returns a text representation of a PRAT
extern std::wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision); extern std::wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision);
// converts a PRAT into a PNUMBER
extern PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision);
// flattens a PRAT by converting it to a PNUMBER and back to a PRAT
extern void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision);
extern long numtolong(_In_ PNUMBER pnum, uint32_t radix ); extern long numtolong(_In_ PNUMBER pnum, uint32_t radix );
extern long rattolong(_In_ PRAT prat, uint32_t radix, int32_t precision); extern long rattolong(_In_ PRAT prat, uint32_t radix, int32_t precision);

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.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -291,19 +291,18 @@ void intrat( PRAT *px, uint32_t radix, int32_t precision)
// and only if the bottom part is not one. // and only if the bottom part is not one.
if ( !zernum( (*px)->pp ) && !equnum( (*px)->pq, num_one ) ) if ( !zernum( (*px)->pp ) && !equnum( (*px)->pq, num_one ) )
{ {
wstring ratStr = RatToString(*px, FMT_FLOAT, radix, precision); flatrat(*px, radix, precision);
PNUMBER pnum = StringToNumber(ratStr, radix, precision);
destroyrat( *px );
*px = numtorat( pnum, radix);
destroynum( pnum );
// Subtract the fractional part of the rational
PRAT pret = nullptr; PRAT pret = nullptr;
DUPRAT(pret,*px); DUPRAT(pret,*px);
modrat( &pret, rat_one ); modrat( &pret, rat_one );
subrat( px, pret, precision); subrat( px, pret, precision);
destroyrat( pret ); destroyrat( pret );
// Simplify the value if possible to resolve rounding errors
flatrat(*px, radix, precision);
} }
} }
@ -475,7 +474,7 @@ void scale( PRAT *px, PRAT scalefact, uint32_t radix, int32_t precision )
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
// scaleing 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 )
@ -510,7 +509,7 @@ void scale2pi( PRAT *px, uint32_t radix, int32_t precision )
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
// scaleing 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 )

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.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -134,7 +134,7 @@ void sinanglerat( _Inout_ PRAT *pa, ANGLE_TYPE angletype, uint32_t radix, int32_
// //
// ARGUMENTS: x PRAT representation of number to take the cosine of // ARGUMENTS: x PRAT representation of number to take the cosine of
// //
// RETURN: cosin of x in PRAT form. // RETURN: cosine of x in PRAT form.
// //
// EXPLANATION: This uses Taylor series // EXPLANATION: This uses Taylor series
// //

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"
@ -1024,7 +1024,7 @@ void UnitConverter::Calculate()
} }
/// <summary> /// <summary>
/// Trims out any trailing zeroes or decimals in the given input string /// Trims out any trailing zeros or decimals in the given input string
/// </summary> /// </summary>
/// <param name="input">wstring to trim</param> /// <param name="input">wstring to trim</param>
void UnitConverter::TrimString(wstring& returnString) void UnitConverter::TrimString(wstring& returnString)

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
@ -61,7 +61,7 @@ namespace CalculatorApp { namespace Common
} }
} }
// Implementented methods // Implemented methods
virtual bool MoveCurrentTo(Platform::Object^ item) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentTo virtual bool MoveCurrentTo(Platform::Object^ item) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentTo
{ {
if (item) if (item)

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"
@ -23,8 +23,8 @@ int NarratorAnnouncementHostFactory::Initialize()
} }
// For now, there are two type of announcement hosts. // For now, there are two type of announcement hosts.
// We'd prefer to use Notification if it's available and fallback to LiveRegion // We'd prefer to use Notification if it's available and fall back to LiveRegion
// if not. The availabilty of the host depends on the version of the OS the app is running on. // if not. The availability of the host depends on the version of the OS the app is running on.
// When the app switches to min version RS3, the LiveRegionHost can be removed and we will always // When the app switches to min version RS3, the LiveRegionHost can be removed and we will always
// use NotificationHost. // use NotificationHost.
// TODO - MSFT 12735088 // TODO - MSFT 12735088

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// This class provides the concrete implemenation 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"

View file

@ -88,7 +88,7 @@ task<String^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupTyp
// Retrieve the text in the clipboard // Retrieve the text in the clipboard
auto dataPackageView = Clipboard::GetContent(); auto dataPackageView = Clipboard::GetContent();
// TODO: Suport all formats supported by ClipboardHasText // TODO: Support all formats supported by ClipboardHasText
//-- add support to avoid pasting of expressions like 12 34(as of now we allow 1234) //-- add support to avoid pasting of expressions like 12 34(as of now we allow 1234)
//-- add support to allow pasting for expressions like .2 , -.2 //-- add support to allow pasting for expressions like .2 , -.2
//-- add support to allow pasting for expressions like 1.3e12(as of now we allow 1.3e+12) //-- add support to allow pasting for expressions like 1.3e12(as of now we allow 1.3e+12)

View file

@ -154,7 +154,7 @@ void DateCalculationEngine::GetDateDifference(_In_ DateTime date1, _In_ DateTime
if (tempDaysDiff < 0) if (tempDaysDiff < 0)
{ {
// pivotDate has gone over the end date; start from the begining of this unit // pivotDate has gone over the end date; start from the beginning of this unit
differenceInDates[unitIndex] -= 1; differenceInDates[unitIndex] -= 1;
pivotDate = tempPivotDate; pivotDate = tempPivotDate;
pivotDate = AdjustCalendarDate(pivotDate, dateUnit, static_cast<int>(differenceInDates[unitIndex])); pivotDate = AdjustCalendarDate(pivotDate, dateUnit, static_cast<int>(differenceInDates[unitIndex]));

View file

@ -32,7 +32,7 @@ namespace CalculatorApp
// Sometimes, like with popups, escape is treated as special and even // Sometimes, like with popups, escape is treated as special and even
// though it is handled we get it passed through to us. In those cases // though it is handled we get it passed through to us. In those cases
// we need to be able to ignore it (looking at e->Hanlded isn't sufficient // we need to be able to ignore it (looking at e->Handled isn't sufficient
// because that always returns true). // because that always returns true).
// The onlyOnce flag is used to indicate whether we should only ignore the // The onlyOnce flag is used to indicate whether we should only ignore the
// next escape, or keep ignoring until you explicitly HonorEscape. // next escape, or keep ignoring until you explicitly HonorEscape.

View file

@ -104,7 +104,7 @@ namespace CalculatorApp
TraceLogger(); TraceLogger();
// 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 upto 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

View file

@ -616,7 +616,7 @@ void StandardCalculatorViewModel::OnButtonPressed(Object^ parameter)
// Also, the Primary Display Value should not show in exponential format. // Also, the Primary Display Value should not show in exponential format.
// Hence the check below to ensure parity with Desktop Calculator. // Hence the check below to ensure parity with Desktop Calculator.
// Clear the FE mode if the switching to StandardMode, since 'C'/'CE' in StandardMode // Clear the FE mode if the switching to StandardMode, since 'C'/'CE' in StandardMode
// doesn't honour the FE button. // doesn't honor the FE button.
if (IsFToEChecked) if (IsFToEChecked)
{ {
IsFToEChecked = false; IsFToEChecked = false;

View file

@ -74,7 +74,7 @@ namespace CalculatorApp
Platform::String^ get() { return ref new Platform::String(m_original.abbreviation.c_str()); } Platform::String^ get() { return ref new Platform::String(m_original.abbreviation.c_str()); }
} }
// This method is used to return the desired autonamtion name for default unit in UnitConveter combo box. // This method is used to return the desired automation name for default unit in UnitConveter combo box.
Platform::String^ ToString() override Platform::String^ ToString() override
{ {
return AccessibleName; return AccessibleName;

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
@ -29,7 +29,7 @@ namespace CalculatorApp
AppLifecycleLogger(); AppLifecycleLogger();
// 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 upto 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

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"
@ -154,7 +154,7 @@ void CalculationResult::OnIsInErrorPropertyChanged(bool /*oldValue*/, bool newVa
if (newValue) if (newValue)
{ {
// If there's an error message we need to override the normal display font // If there's an error message we need to override the normal display font
// with the font appropiate for this language. This is because the error // with the font appropriate for this language. This is because the error
// message is localized and therefore can contain characters that are not // message is localized and therefore can contain characters that are not
// available in the normal font. // available in the normal font.
// We use UIText as the font type because this is the most common font type to use // We use UIText as the font type because this is the most common font type to use

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"
@ -201,7 +201,7 @@ void OverflowTextBlock::UnregisterEventHandlers()
auto borderContainer = safe_cast<Border^>(GetTemplateChild("expressionborder")); auto borderContainer = safe_cast<Border^>(GetTemplateChild("expressionborder"));
// Adding an extra check, incase the returned template is null // Adding an extra check, in case the returned template is null
if (borderContainer != nullptr) if (borderContainer != nullptr)
{ {
borderContainer->PointerEntered -= m_pointerEnteredEventToken; borderContainer->PointerEntered -= m_pointerEnteredEventToken;

View file

@ -166,7 +166,7 @@ void CalculatorProgrammerBitFlipPanel::OnBitToggled(_In_ Object^ sender, _In_ Ro
// Any input from the Numpad may also result in toggling the bit as their state is bound to the BinaryDisplayValue. // Any input from the Numpad may also result in toggling the bit as their state is bound to the BinaryDisplayValue.
// Also, if the mode is switched to other Calculator modes when the BitFlip panel is open, // Also, if the mode is switched to other Calculator modes when the BitFlip panel is open,
// a race condition exists in which the IsProgrammerMode property is still true and the UpdatePrimaryResult() is called, // a race condition exists in which the IsProgrammerMode property is still true and the UpdatePrimaryResult() is called,
// which continously alters the Display Value and the state of the Bit Flip buttons. // which continuously alters the Display Value and the state of the Bit Flip buttons.
if ((Model->IsBitFlipChecked) if ((Model->IsBitFlipChecked)
&& Model->IsProgrammer) && Model->IsProgrammer)
{ {

View file

@ -116,7 +116,7 @@ void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
void MainPage::WindowSizeChanged(_In_ Platform::Object^ /*sender*/, _In_ Windows::UI::Core::WindowSizeChangedEventArgs^ e) void MainPage::WindowSizeChanged(_In_ Platform::Object^ /*sender*/, _In_ Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{ {
// We dont use layout aware page's view states, we have our own // We don't use layout aware page's view states, we have our own
UpdateViewState(); UpdateViewState();
} }
@ -321,7 +321,7 @@ void MainPage::EnsureCalculator()
CalcHolder->Child = m_calculator; CalcHolder->Child = m_calculator;
// Calculator's "default" state is visibile, but if we get delay loaded // Calculator's "default" state is visible, but if we get delay loaded
// when in converter, we should not be visible. This is not a problem for converter // when in converter, we should not be visible. This is not a problem for converter
// since it's default state is hidden. // since it's default state is hidden.
ShowHideControls(this->Model->Mode); ShowHideControls(this->Model->Mode);

View file

@ -48,7 +48,7 @@ void Memory::MemoryListItemClick(_In_ Object^ sender, _In_ ItemClickEventArgs^ e
{ {
MemoryItemViewModel^ memorySlot = safe_cast<MemoryItemViewModel^>(e->ClickedItem); MemoryItemViewModel^ memorySlot = safe_cast<MemoryItemViewModel^>(e->ClickedItem);
// Incase the memory list is clicked and enter is pressed, // In case the memory list is clicked and enter is pressed,
// On Item clicked event gets fired and e->ClickedItem is Null. // On Item clicked event gets fired and e->ClickedItem is Null.
if (memorySlot != nullptr) if (memorySlot != nullptr)
{ {

View file

@ -102,7 +102,7 @@
<!-- <!--
This is the only button in all of the app that should ever have a explicit reference to KeyboardShortcutManager in Xaml This is the only button in all of the app that should ever have a explicit reference to KeyboardShortcutManager in Xaml
this is needed because we need to have at least 1 refernece from Xaml so the right metadata is generated for the this is needed because we need to have at least 1 reference from Xaml so the right metadata is generated for the
KeyboardShortcutManager class, otherwise the Xaml will stop parsing and the app won't boot therefore: KeyboardShortcutManager class, otherwise the Xaml will stop parsing and the app won't boot therefore:
DO NOT REMOVE the common:KeyboardShortcutManager.Character from this element, it's value will be overwritten by the DO NOT REMOVE the common:KeyboardShortcutManager.Character from this element, it's value will be overwritten by the
string coming from the RESW file string coming from the RESW file

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.
// //
@ -72,7 +72,7 @@ SupplementaryResults::SupplementaryResults() :
void SupplementaryResults::RefreshData() void SupplementaryResults::RefreshData()
{ {
// Copy the list so that when we chop stuff off, we dont modify the original // Copy the list so that when we chop stuff off, we don't modify the original
// complete list. // complete list.
m_data->Clear(); m_data->Clear();
for(SupplementaryResult^ sr : safe_cast<UnitConverterViewModel^>(this->DataContext)->SupplementaryResults) for(SupplementaryResult^ sr : safe_cast<UnitConverterViewModel^>(this->DataContext)->SupplementaryResults)

View file

@ -109,7 +109,7 @@ namespace CalculatorApp
that->InvokeWindowClosingHandlers(); that->InvokeWindowClosingHandlers();
// This is to ensure InvokeWindowClosingHandlers is be done before RemoveWindowFromMap // This is to ensure InvokeWindowClosingHandlers is be done before RemoveWindowFromMap
// If InvokeWindowClosingHandlers throws any exception we want it to crash the application // If InvokeWindowClosingHandlers throws any exception we want it to crash the application
// so we are ok not setting closingHandlersCompletedEvent in that case // so we are OK not setting closingHandlersCompletedEvent in that case
closingHandlersCompletedEvent.set(); closingHandlersCompletedEvent.set();
that->m_coreDispatcher->StopProcessEvents(); that->m_coreDispatcher->StopProcessEvents();
Window::Current->Close(); Window::Current->Close();

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"
@ -83,7 +83,7 @@ namespace CalculatorUnitTests
VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds."); VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds.");
VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds."); VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds.");
VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds."); VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds.");
VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify leading zeroes are ignored."); VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify leading zeros are ignored.");
} }
TEST_METHOD(TryAddDigitMaxCount) TEST_METHOD(TryAddDigitMaxCount)
{ {