mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-22 22:23:29 -07:00
Optimize how we calculate the number of digits in the integer part and don't trim the value when used by the currency converter
This commit is contained in:
parent
b91449a0ae
commit
ad7a9926a5
2 changed files with 49 additions and 38 deletions
|
@ -858,18 +858,17 @@ void UnitConverter::Calculate()
|
||||||
{
|
{
|
||||||
double currentValue = stod(m_currentDisplay);
|
double currentValue = stod(m_currentDisplay);
|
||||||
double returnValue = Convert(currentValue, conversionTable[m_toType]);
|
double returnValue = Convert(currentValue, conversionTable[m_toType]);
|
||||||
|
|
||||||
|
auto isCurrencyConverter = m_currencyDataLoader != nullptr && m_currencyDataLoader->SupportsCategory(this->m_currentCategory);
|
||||||
|
if (isCurrencyConverter)
|
||||||
|
{
|
||||||
|
// We don't need to trim the value when it's a currency.
|
||||||
m_returnDisplay = RoundSignificant(returnValue, MAXIMUMDIGITSALLOWED);
|
m_returnDisplay = RoundSignificant(returnValue, MAXIMUMDIGITSALLOWED);
|
||||||
TrimString(m_returnDisplay);
|
TrimString(m_returnDisplay);
|
||||||
int numPreDecimal = (int)m_returnDisplay.size();
|
|
||||||
if (m_returnDisplay.find(L'.') != m_returnDisplay.npos)
|
|
||||||
{
|
|
||||||
numPreDecimal = (int)m_returnDisplay.find(L'.');
|
|
||||||
}
|
}
|
||||||
if (returnValue < 0)
|
else
|
||||||
{
|
{
|
||||||
numPreDecimal--;
|
int numPreDecimal = returnValue == 0 ? 0 : (1 + (int)log10(abs(returnValue)));
|
||||||
}
|
|
||||||
|
|
||||||
if (numPreDecimal > MAXIMUMDIGITSALLOWED || (returnValue != 0 && abs(returnValue) < MINIMUMDECIMALALLOWED))
|
if (numPreDecimal > MAXIMUMDIGITSALLOWED || (returnValue != 0 && abs(returnValue) < MINIMUMDECIMALALLOWED))
|
||||||
{
|
{
|
||||||
wstringstream out(wstringstream::out);
|
wstringstream out(wstringstream::out);
|
||||||
|
@ -878,16 +877,7 @@ void UnitConverter::Calculate()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
returnValue = stod(m_returnDisplay);
|
int currentNumberSignificantDigits = GetNumberSignificantDigits(m_currentDisplay);
|
||||||
|
|
||||||
auto currentDisplayTrimmed = m_currentDisplay;
|
|
||||||
TrimString(currentDisplayTrimmed);
|
|
||||||
int currentNumberSignificantDigits = static_cast<int>(currentDisplayTrimmed.size());
|
|
||||||
if (currentDisplayTrimmed.find(L'.') != currentDisplayTrimmed.npos)
|
|
||||||
--currentNumberSignificantDigits;
|
|
||||||
if (currentValue < 0)
|
|
||||||
--currentNumberSignificantDigits;
|
|
||||||
|
|
||||||
int precision = 0;
|
int precision = 0;
|
||||||
if (abs(returnValue) < OPTIMALDECIMALALLOWED)
|
if (abs(returnValue) < OPTIMALDECIMALALLOWED)
|
||||||
{
|
{
|
||||||
|
@ -903,6 +893,7 @@ void UnitConverter::Calculate()
|
||||||
}
|
}
|
||||||
m_returnHasDecimal = (m_returnDisplay.find(L'.') != m_returnDisplay.npos);
|
m_returnHasDecimal = (m_returnDisplay.find(L'.') != m_returnDisplay.npos);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
UpdateViewModel();
|
UpdateViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,9 +901,9 @@ void UnitConverter::Calculate()
|
||||||
/// Trims out any trailing zeros 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(_Inout_ wstring& returnString)
|
||||||
{
|
{
|
||||||
if (returnString.find(L'.') == m_returnDisplay.npos)
|
if (returnString.find(L'.') == returnString.npos)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -932,6 +923,24 @@ void UnitConverter::TrimString(wstring& returnString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get number of significant digits (integer part + fractional part) of a number</summary>
|
||||||
|
/// <param name="value">the number</param>
|
||||||
|
unsigned int UnitConverter::GetNumberSignificantDigits(std::wstring value)
|
||||||
|
{
|
||||||
|
TrimString(value);
|
||||||
|
int currentNumberSignificantDigits = value.size();
|
||||||
|
if (value.find(L'.') != value.npos)
|
||||||
|
{
|
||||||
|
--currentNumberSignificantDigits;
|
||||||
|
}
|
||||||
|
if (value.find(L'-') != value.npos)
|
||||||
|
{
|
||||||
|
--currentNumberSignificantDigits;
|
||||||
|
}
|
||||||
|
return currentNumberSignificantDigits;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rounds the given double to the given number of significant digits
|
/// Rounds the given double to the given number of significant digits
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -279,9 +279,7 @@ namespace UnitConversionManager
|
||||||
double Convert(double value, ConversionData conversionData);
|
double Convert(double value, ConversionData conversionData);
|
||||||
std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested();
|
std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested();
|
||||||
void ClearValues();
|
void ClearValues();
|
||||||
void TrimString(std::wstring& input);
|
|
||||||
void InitializeSelectedUnits();
|
void InitializeSelectedUnits();
|
||||||
std::wstring RoundSignificant(double num, int numSignificant);
|
|
||||||
Category StringToCategory(const std::wstring& w);
|
Category StringToCategory(const std::wstring& w);
|
||||||
std::wstring CategoryToString(const Category& c, const wchar_t* delimiter);
|
std::wstring CategoryToString(const Category& c, const wchar_t* delimiter);
|
||||||
std::wstring UnitToString(const Unit& u, const wchar_t* delimiter);
|
std::wstring UnitToString(const Unit& u, const wchar_t* delimiter);
|
||||||
|
@ -292,6 +290,10 @@ namespace UnitConversionManager
|
||||||
std::shared_ptr<IConverterDataLoader> GetDataLoaderForCategory(const Category& category);
|
std::shared_ptr<IConverterDataLoader> GetDataLoaderForCategory(const Category& category);
|
||||||
std::shared_ptr<ICurrencyConverterDataLoader> GetCurrencyConverterDataLoader();
|
std::shared_ptr<ICurrencyConverterDataLoader> GetCurrencyConverterDataLoader();
|
||||||
|
|
||||||
|
static void TrimString(_Inout_ std::wstring& input);
|
||||||
|
static unsigned int GetNumberSignificantDigits(std::wstring value);
|
||||||
|
static std::wstring RoundSignificant(double num, int numSignificant);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IConverterDataLoader> m_dataLoader;
|
std::shared_ptr<IConverterDataLoader> m_dataLoader;
|
||||||
std::shared_ptr<IConverterDataLoader> m_currencyDataLoader;
|
std::shared_ptr<IConverterDataLoader> m_currencyDataLoader;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue