Fixes#382
Description of the changes:
Add Pyeong as an Area conversion unit.
Pyeong shows up only if the user's current region is Korea ( i.e. region is either KP or KR ).
Added Korean translation for Pyeong (평). For other locales, we default to English ( Pyeong ).
How changes were validated:
Manually tested the below
For non-Korean regions, Pyeong does not show up.
Korean region with Korean locale => Pyeong shows up and Pyeong is correctly translated.
pyeong_Korean
Korean region with English locale => Pyeong shows up and Pyeong is in English.
pyeong_English
Korean region with simplified Chinese locale => Pyeong shows up and Pyeong is in English.
pyeong_Chinese
## Fixes#111
> The modulo operator on this calculator gives the result that is different to the most used calculators.
The current `modrate` function is the equivalent of rem(...)/remainder(...), not mod(...)/modulo(...) available in some popular Math apps.
### Description of the changes:
- rename `modrate` in `remrate` to be more accurate.
- add `modrate`, calculating modulo similarly to Matlab, Bing, Google calculator, Maxima, Wolfram Alpha and Microsoft Excel
- Add `RationalMath::Mod` using `modrate` as an alternative to `Rational::operator%` using `remrate`
- Add a helper `SIGN` to retrieve the sign of a `Rational`.
- modify `CalcEngine` to use `modrate` in Normal and Scientific mode and `remrate` in Programmer mode.
### How changes were validated:
- manually and unit tests added
Fixes#260
Description of the changes:
prevent UnitConverterViewModel to reset values when users click on update rates.
recompute UnitConverter's caches (m_ratioMap and m_categoryToUnits) once rates are updated (but check first if the user did/didn't change the category)
How changes were validated:
Manually tested with fake currency rates (HTTP responses modified on the fly via FiddlerCore)
Verified that it works no matter the selected field (From or To)
Verified that the currencies selected are kept after a refresh
Description of the changes:
Currently Calculator handles strings by defining integers for each type of function that can be performed, this integer will eventually correspond with an index in s_engineStrings which holds the corresponding display string for each function. Some functions such as Sin can have multiple strings (degrees, rads, grads, inverse). Functions like Sin are mapped to another array called "rgUfne" where a new integer is given depending on the output string which will then be given to s_engineStrings. The new integer returned by the "rgUfne" array runs the risk of overlapping with any new functions that may be added in CCommand.h. Furthermore, it is expected that the strings in s_engineStrings and rgUfne are defined in a particular order (not necessarily sequential), otherwise the logic will break. This makes adding new strings for new functions confusing and difficult, since a lot of the logic is not clearly defined.
This PR attempts to make this a bit simpler by changing the s_engineStrings and rgUfne arrays to be unordered_maps instead of arrays. For s_engineStrings the keys will now be strings, allowing the existing logic for indexing to be used by simply converting the number into a string to access the value. This will also allow us to create keys in the future that are not limited to integers but to strings that hold more meaning.
The rgUfne array will also be updated to be a map that will take in an integer and give you the corresponding string that can be passed to s_engineStrings. The UFNE object in the rgUfne array will also be updated to hold all the possible string keys for a function, instead of indexing them on other numbers that may overlap with existing definitions.
Now to add a new string for a new IDC_FOO function, we would just need to add the "FooString" resource keys to the g_sids array and use the updated rgUfne map to link the IDC_FOO value to the corresponding "FooString" resource key. This way the resource key can be a meaningful string, and not an integer that must be in any particular order.
How changes were validated:
Tested each function manually in standard, scientific, and programmer modes.
The conditional m_precedenceOpCount >= 0 was always true because m_precendenceOpCount is an unsigned type. Update the conditional to simply be true and rely on a break statement in the loop. Although this member variable used to be a signed type, in practice, the value was never less than 0.
How changes were validated:
Manual. Unit tests pass locally.
Description of the changes:
Disable Windows-provided min/max macros using the NOMINMAX flag. Add the flag to each project's pch to disable the macros across the solution.
How changes were validated:
Project builds.
Unit tests pass.
Smoke tests.
Fixes#362.
I have no idea if it is required to be `sealed`, I have seen no `^`
operator which makes me think it could be a regular C++ code, barring
the concurrency stuff.
Fixing some nested if() statements and reducing indentation levels.
Making some sections less verbose, e.g:
if (a == 1)
{
b = true;
}
else
{
b = false;
}
↓
b = (a == 1)
Fixed comments that were inconsistent with the style guidelines described in C++ core guidelines and the modern C++/WinRT language projections and removed trailing whitespace.
Inserted a space after the beginning of the comment so the text wasn't touching the // on all occurrences.
Removed all occurrences of trailing whitespace
This change makes the 73 variables in ratconst.h actually
inline const, which allows them to move from the mutable .data
section of the executable, and into the read-only .rdata
section instead.
Moving data to the .rdata section has a number of benefits,
such as preventing possible corruption due to stray writes,
or other memory corruption.
Additionally, the initialization at run-time start-up is no
longer needed, so there is also a reduction in the .text
(code) section as well.
As a result the overall size of the Calculator.exe binary
(on x64 Release builds) decreases by 1,536 bytes (or ~1.5 KB)
with no change in behavior other than a small performance benefit.
### Description of the changes:
There are currently 11 copies of the `EMPTY_UNIT` object in the
`Calculator.exe` binary, which not only wastes space/footprint in the
binary itself, but also means that each copy must be separately
initialized, which effects performance.
The reason for this is that the object is defined in a shared header
file, which then is included by multiple .cpp files, causing each
translation unit (.obj) to get a full complete copy of the object.
By marking the object as `inline` we can
instruct the linker to define the object once, as we do
not need to have 11 unique versions of the EMPTY_UNIT object,
we only need 1.
The net result is that the `Calculator.exe` binary size is reduced by
2,560 bytes (or 2.5 KB) with no change in behavior, other than
the small performance benefit of not initializing 10 redundant copies
of the object.
### How changes were validated:
- Manually tested.
Looks like the comment on IsEven should read this way instead of "The assumption here is its numerator is 1 and we are testing the numerator is even or not"
When building for x64, the compiler complains:
warning C4267: 'argument': conversion from 'size_t' to 'ULONG', possible loss of data
In practice, the number string will not exceed a ULONG in length.
* Convert Rational::Negate to an operator override
* Convert Rational::Add to + and += operator overrides.
* Convert Rational::Sub to - and -= operator overrides.
* Convert Rational::Div and ::Mul to use /, /=, *, *= operator overrides.
* Convert Rational::Mod to use %= and % operator overrides
* Convert Rational::Rsh and ::Lsh to use >>=, >>, <<=, << operator overrides
* Convert Rational::And, ::Or, ::Xor to use &=, &, |=, |, ^=, ^ operator overrides
* Convert Rational relational functions to operator overrides
* Remove unnecessary precision arguments from Rational class and remove use of explicit Rational constructors in favor of implicit conversions for value types
* Remove unnecessary precision variable from RationalMath operations
* Replace unnecessary Rational::Not with Xor operation
* Remove unnecessary Rational::IsZero() in favor of == 0 comparisons
* Fix rounding issues in ratpak that result from using large precisions.
* Move assignment stmt out of IsCurrentTooBigForTrig
- Separates values from the representation (base/radix) of those values.
- Uses a single base for all values represented as Rationals.
- Rationals are converted to/from a specific base when they are converted to/from strings.
This change moves the RADIX_TYPE enum into its own header. This resolves a compilation error and reduces the dependency graph by allowing RadixToStringConverter to include just the enum header rather than the entire CalcEngine header.
Change verified by ensuring Calculator build locally.
* Converts NumObj* functions to use Rationals. Places new functions under CalcEngine::RationalMath namespace
* Moves functions that correspond to an operator to the Rational class with intent to convert to operators in the future
* Consolidates use of RatPack's NUMBER and RAT data types to Number/Rational classes and RationalMath namespace.