Merge master into feature/GraphingCalculator branch (#660)
This commit is contained in:
@@ -951,7 +951,7 @@ int CCalcEngine::GetCurrentRadix()
|
||||
return m_radix;
|
||||
}
|
||||
|
||||
wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision)
|
||||
wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix)
|
||||
{
|
||||
Rational rat = (m_bRecord ? m_input.ToRational(m_radix, m_precision) : m_currentVal);
|
||||
|
||||
@@ -964,7 +964,14 @@ wstring CCalcEngine::GetCurrentResultForRadix(uint32_t radix, int32_t precision)
|
||||
ChangeConstants(m_radix, m_precision);
|
||||
}
|
||||
|
||||
return GroupDigitsPerRadix(numberString, radix);
|
||||
if (groupDigitsPerRadix)
|
||||
{
|
||||
return GroupDigitsPerRadix(numberString, radix);
|
||||
}
|
||||
else
|
||||
{
|
||||
return numberString;
|
||||
}
|
||||
}
|
||||
|
||||
wstring CCalcEngine::GetStringForDisplay(Rational const& rat, uint32_t radix)
|
||||
|
@@ -45,8 +45,8 @@
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.18362.0</WindowsTargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<!-- This has to be exactly in this place for this to work -->
|
||||
@@ -309,6 +309,7 @@
|
||||
<ClInclude Include="Ratpack\CalcErr.h" />
|
||||
<ClInclude Include="Ratpack\ratconst.h" />
|
||||
<ClInclude Include="Ratpack\ratpak.h" />
|
||||
<ClInclude Include="NumberFormattingUtils.h" />
|
||||
<ClInclude Include="UnitConverter.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -349,6 +350,7 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NumberFormattingUtils.cpp" />
|
||||
<ClCompile Include="UnitConverter.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
@@ -89,6 +89,7 @@
|
||||
<ClCompile Include="CEngine\RationalMath.cpp">
|
||||
<Filter>CEngine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NumberFormattingUtils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Command.h" />
|
||||
@@ -160,5 +161,6 @@
|
||||
<ClInclude Include="Header Files\RationalMath.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NumberFormattingUtils.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
@@ -37,15 +37,6 @@ namespace CalculationManager
|
||||
CCalcEngine::InitialOneTimeOnlySetup(*m_resourceProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructor for CalculatorManager
|
||||
/// Ends two CCalcEngine
|
||||
/// </summary>
|
||||
CalculatorManager::~CalculatorManager()
|
||||
{
|
||||
this->MemorizedNumberClearAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call the callback function using passed in IDisplayHelper.
|
||||
/// Used to set the primary display value on ViewModel
|
||||
@@ -622,9 +613,9 @@ namespace CalculationManager
|
||||
}
|
||||
}
|
||||
|
||||
wstring CalculatorManager::GetResultForRadix(uint32_t radix, int32_t precision)
|
||||
wstring CalculatorManager::GetResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix)
|
||||
{
|
||||
return m_currentCalculatorEngine ? m_currentCalculatorEngine->GetCurrentResultForRadix(radix, precision) : L"";
|
||||
return m_currentCalculatorEngine ? m_currentCalculatorEngine->GetCurrentResultForRadix(radix, precision, groupDigitsPerRadix) : L"";
|
||||
}
|
||||
|
||||
void CalculatorManager::SetPrecision(int32_t precision)
|
||||
|
@@ -103,7 +103,6 @@ namespace CalculationManager
|
||||
void MemoryItemChanged(unsigned int indexOfMemory) override;
|
||||
|
||||
CalculatorManager(ICalcDisplay* displayCallback, IResourceProvider* resourceProvider);
|
||||
~CalculatorManager();
|
||||
|
||||
void Reset(bool clearMemory = true);
|
||||
void SetStandardMode();
|
||||
@@ -125,7 +124,7 @@ namespace CalculationManager
|
||||
}
|
||||
void SetRadix(RADIX_TYPE iRadixType);
|
||||
void SetMemorizedNumbersString();
|
||||
std::wstring GetResultForRadix(uint32_t radix, int32_t precision);
|
||||
std::wstring GetResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix);
|
||||
void SetPrecision(int32_t precision);
|
||||
void UpdateMaxIntDigits();
|
||||
wchar_t DecimalSeparator();
|
||||
|
@@ -137,6 +137,7 @@ void COpndCommand::AppendCommand(int command)
|
||||
{
|
||||
m_commands->Append(command);
|
||||
}
|
||||
|
||||
if (command == IDC_PNT)
|
||||
{
|
||||
m_fDecimal = true;
|
||||
@@ -256,38 +257,30 @@ const wstring& COpndCommand::GetToken(wchar_t decimalSymbol)
|
||||
}
|
||||
|
||||
// Remove zeros
|
||||
bool fDigitsFound = false;
|
||||
int trimIdx = 0;
|
||||
for (unsigned int i = 0; i < m_token.size(); i++)
|
||||
{
|
||||
if (m_token.at(i) != chZero)
|
||||
{
|
||||
if (m_token.at(i) == decimalSymbol)
|
||||
{
|
||||
trimIdx = i - 1;
|
||||
m_token.erase(0, i - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
trimIdx = i;
|
||||
m_token.erase(0, i);
|
||||
}
|
||||
fDigitsFound = true;
|
||||
break;
|
||||
|
||||
if (m_fNegative)
|
||||
{
|
||||
m_token.insert(0, &chNegate);
|
||||
}
|
||||
|
||||
return m_token;
|
||||
}
|
||||
}
|
||||
|
||||
if (fDigitsFound)
|
||||
{
|
||||
m_token.erase(0, trimIdx);
|
||||
if (m_fNegative)
|
||||
{
|
||||
m_token.insert(0, &chNegate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_token.clear();
|
||||
m_token.append(&chZero);
|
||||
}
|
||||
m_token.clear();
|
||||
m_token.append(&chZero);
|
||||
|
||||
return m_token;
|
||||
}
|
||||
|
@@ -75,7 +75,7 @@ public:
|
||||
void SettingsChanged();
|
||||
bool IsCurrentTooBigForTrig();
|
||||
int GetCurrentRadix();
|
||||
std::wstring GetCurrentResultForRadix(uint32_t radix, int32_t precision);
|
||||
std::wstring GetCurrentResultForRadix(uint32_t radix, int32_t precision, bool groupDigitsPerRadix);
|
||||
void ChangePrecision(int32_t precision)
|
||||
{
|
||||
m_precision = precision;
|
||||
|
84
src/CalcManager/NumberFormattingUtils.cpp
Normal file
84
src/CalcManager/NumberFormattingUtils.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "pch.h"
|
||||
#include "NumberFormattingUtils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace CalcManager::NumberFormattingUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Trims out any trailing zeros or decimals in the given input string
|
||||
/// </summary>
|
||||
/// <param name="number">number to trim</param>
|
||||
void TrimTrailingZeros(_Inout_ wstring& number)
|
||||
{
|
||||
if (number.find(L'.') == wstring::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wstring::iterator iter;
|
||||
for (iter = number.end() - 1;; iter--)
|
||||
{
|
||||
if (*iter != L'0')
|
||||
{
|
||||
number.erase(iter + 1, number.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*(number.end() - 1) == L'.')
|
||||
{
|
||||
number.erase(number.end() - 1, number.end());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get number of digits (whole number part + decimal part)</summary>
|
||||
/// <param name="value">the number</param>
|
||||
unsigned int GetNumberDigits(wstring value)
|
||||
{
|
||||
TrimTrailingZeros(value);
|
||||
unsigned int numberSignificantDigits = static_cast<unsigned int>(value.size());
|
||||
if (value.find(L'.') != wstring::npos)
|
||||
{
|
||||
--numberSignificantDigits;
|
||||
}
|
||||
if (value.find(L'-') != wstring::npos)
|
||||
{
|
||||
--numberSignificantDigits;
|
||||
}
|
||||
return numberSignificantDigits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get number of digits (whole number part only)</summary>
|
||||
/// <param name="value">the number</param>
|
||||
unsigned int GetNumberDigitsWholeNumberPart(double value)
|
||||
{
|
||||
return value == 0 ? 1 : (1 + (int)log10(abs(value)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the given double to the given number of significant digits
|
||||
/// </summary>
|
||||
/// <param name="num">input double</param>
|
||||
/// <param name="numSignificant">int number of significant digits to round to</param>
|
||||
wstring RoundSignificantDigits(double num, int numSignificant)
|
||||
{
|
||||
wstringstream out(wstringstream::out);
|
||||
out << fixed;
|
||||
out.precision(numSignificant);
|
||||
out << num;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a Number to Scientific Notation
|
||||
/// </summary>
|
||||
/// <param name="number">number to convert</param>
|
||||
wstring ToScientificNumber(double number)
|
||||
{
|
||||
wstringstream out(wstringstream::out);
|
||||
out << scientific << number;
|
||||
return out.str();
|
||||
}
|
||||
}
|
15
src/CalcManager/NumberFormattingUtils.h
Normal file
15
src/CalcManager/NumberFormattingUtils.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace CalcManager::NumberFormattingUtils
|
||||
{
|
||||
void TrimTrailingZeros(_Inout_ std::wstring& input);
|
||||
unsigned int GetNumberDigits(std::wstring value);
|
||||
unsigned int GetNumberDigitsWholeNumberPart(double value);
|
||||
std::wstring RoundSignificantDigits(double value, int numberSignificantDigits);
|
||||
std::wstring ToScientificNumber(double number);
|
||||
}
|
@@ -7,9 +7,11 @@
|
||||
#include <algorithm> // for std::sort
|
||||
#include "Command.h"
|
||||
#include "UnitConverter.h"
|
||||
#include "NumberFormattingUtils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace UnitConversionManager;
|
||||
using namespace CalcManager::NumberFormattingUtils;
|
||||
|
||||
static constexpr uint32_t EXPECTEDSERIALIZEDCATEGORYTOKENCOUNT = 3;
|
||||
static constexpr uint32_t EXPECTEDSERIALIZEDUNITTOKENCOUNT = 6;
|
||||
@@ -178,7 +180,7 @@ void UnitConverter::SwitchActive(const wstring& newValue)
|
||||
swap(m_currentHasDecimal, m_returnHasDecimal);
|
||||
m_returnDisplay = m_currentDisplay;
|
||||
m_currentDisplay = newValue;
|
||||
m_currentHasDecimal = (m_currentDisplay.find(L'.') != m_currentDisplay.npos);
|
||||
m_currentHasDecimal = (m_currentDisplay.find(L'.') != wstring::npos);
|
||||
m_switchedActive = true;
|
||||
|
||||
if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr)
|
||||
@@ -202,7 +204,7 @@ vector<wstring> UnitConverter::StringToVector(const wstring& w, const wchar_t* d
|
||||
size_t delimiterIndex = w.find(delimiter);
|
||||
size_t startIndex = 0;
|
||||
vector<wstring> serializedTokens = vector<wstring>();
|
||||
while (delimiterIndex != w.npos)
|
||||
while (delimiterIndex != wstring::npos)
|
||||
{
|
||||
serializedTokens.push_back(w.substr(startIndex, delimiterIndex - startIndex));
|
||||
startIndex = delimiterIndex + (int)wcslen(delimiter);
|
||||
@@ -634,19 +636,19 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
||||
wstring roundedString;
|
||||
if (abs(entry.value) < 100)
|
||||
{
|
||||
roundedString = RoundSignificant(entry.value, 2);
|
||||
roundedString = RoundSignificantDigits(entry.value, 2);
|
||||
}
|
||||
else if (abs(entry.value) < 1000)
|
||||
{
|
||||
roundedString = RoundSignificant(entry.value, 1);
|
||||
roundedString = RoundSignificantDigits(entry.value, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
roundedString = RoundSignificant(entry.value, 0);
|
||||
roundedString = RoundSignificantDigits(entry.value, 0);
|
||||
}
|
||||
if (stod(roundedString) != 0.0 || m_currentCategory.supportsNegative)
|
||||
{
|
||||
TrimString(roundedString);
|
||||
TrimTrailingZeros(roundedString);
|
||||
returnVector.push_back(make_tuple(roundedString, entry.type));
|
||||
}
|
||||
}
|
||||
@@ -672,21 +674,21 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
|
||||
wstring roundedString;
|
||||
if (abs(entry.value) < 100)
|
||||
{
|
||||
roundedString = RoundSignificant(entry.value, 2);
|
||||
roundedString = RoundSignificantDigits(entry.value, 2);
|
||||
}
|
||||
else if (abs(entry.value) < 1000)
|
||||
{
|
||||
roundedString = RoundSignificant(entry.value, 1);
|
||||
roundedString = RoundSignificantDigits(entry.value, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
roundedString = RoundSignificant(entry.value, 0);
|
||||
roundedString = RoundSignificantDigits(entry.value, 0);
|
||||
}
|
||||
|
||||
// How to work out which is the best whimsical value to add to the vector?
|
||||
if (stod(roundedString) != 0.0)
|
||||
{
|
||||
TrimString(roundedString);
|
||||
TrimTrailingZeros(roundedString);
|
||||
whimsicalReturnVector.push_back(make_tuple(roundedString, entry.type));
|
||||
}
|
||||
}
|
||||
@@ -789,17 +791,27 @@ void UnitConverter::InitializeSelectedUnits()
|
||||
vector<Unit> curUnits = itr->second;
|
||||
if (!curUnits.empty())
|
||||
{
|
||||
// Units may already have been initialized through UnitConverter::RestoreUserPreferences().
|
||||
// Check if they have been, and if so, do not override restored units.
|
||||
bool isFromUnitValid = m_fromType != EMPTY_UNIT && find(curUnits.begin(), curUnits.end(), m_fromType) != curUnits.end();
|
||||
bool isToUnitValid = m_toType != EMPTY_UNIT && find(curUnits.begin(), curUnits.end(), m_toType) != curUnits.end();
|
||||
|
||||
if (isFromUnitValid && isToUnitValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool conversionSourceSet = false;
|
||||
bool conversionTargetSet = false;
|
||||
for (const Unit& cur : curUnits)
|
||||
{
|
||||
if (!conversionSourceSet && cur.isConversionSource)
|
||||
if (!conversionSourceSet && cur.isConversionSource && !isFromUnitValid)
|
||||
{
|
||||
m_fromType = cur;
|
||||
conversionSourceSet = true;
|
||||
}
|
||||
|
||||
if (!conversionTargetSet && cur.isConversionTarget)
|
||||
if (!conversionTargetSet && cur.isConversionTarget && !isToUnitValid)
|
||||
{
|
||||
m_toType = cur;
|
||||
conversionTargetSet = true;
|
||||
@@ -843,100 +855,61 @@ void UnitConverter::Calculate()
|
||||
{
|
||||
m_returnDisplay = m_currentDisplay;
|
||||
m_returnHasDecimal = m_currentHasDecimal;
|
||||
TrimString(m_returnDisplay);
|
||||
TrimTrailingZeros(m_returnDisplay);
|
||||
UpdateViewModel();
|
||||
return;
|
||||
}
|
||||
|
||||
unordered_map<Unit, ConversionData, UnitHash> conversionTable = m_ratioMap[m_fromType];
|
||||
double returnValue = stod(m_currentDisplay);
|
||||
if (conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0)
|
||||
if (AnyUnitIsEmpty() || (conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0))
|
||||
{
|
||||
m_returnDisplay = m_currentDisplay;
|
||||
m_returnHasDecimal = m_currentHasDecimal;
|
||||
TrimString(m_returnDisplay);
|
||||
TrimTrailingZeros(m_returnDisplay);
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = Convert(returnValue, conversionTable[m_toType]);
|
||||
m_returnDisplay = RoundSignificant(returnValue, MAXIMUMDIGITSALLOWED);
|
||||
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)
|
||||
{
|
||||
numPreDecimal--;
|
||||
}
|
||||
double currentValue = stod(m_currentDisplay);
|
||||
double returnValue = Convert(currentValue, conversionTable[m_toType]);
|
||||
|
||||
if (numPreDecimal > MAXIMUMDIGITSALLOWED || (returnValue != 0 && abs(returnValue) < MINIMUMDECIMALALLOWED))
|
||||
auto isCurrencyConverter = m_currencyDataLoader != nullptr && m_currencyDataLoader->SupportsCategory(this->m_currentCategory);
|
||||
if (isCurrencyConverter)
|
||||
{
|
||||
wstringstream out(wstringstream::out);
|
||||
out << scientific << returnValue;
|
||||
m_returnDisplay = out.str();
|
||||
// We don't need to trim the value when it's a currency.
|
||||
m_returnDisplay = RoundSignificantDigits(returnValue, MAXIMUMDIGITSALLOWED);
|
||||
TrimTrailingZeros(m_returnDisplay);
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = stod(m_returnDisplay);
|
||||
wstring returnString;
|
||||
if (m_currentDisplay.size() <= OPTIMALDIGITSALLOWED && abs(returnValue) >= OPTIMALDECIMALALLOWED)
|
||||
int numPreDecimal = GetNumberDigitsWholeNumberPart(returnValue);
|
||||
if (numPreDecimal > MAXIMUMDIGITSALLOWED || (returnValue != 0 && abs(returnValue) < MINIMUMDECIMALALLOWED))
|
||||
{
|
||||
returnString = RoundSignificant(returnValue, OPTIMALDIGITSALLOWED - min(numPreDecimal, OPTIMALDIGITSALLOWED));
|
||||
m_returnDisplay = ToScientificNumber(returnValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
returnString = RoundSignificant(returnValue, MAXIMUMDIGITSALLOWED - min(numPreDecimal, MAXIMUMDIGITSALLOWED));
|
||||
int currentNumberSignificantDigits = GetNumberDigits(m_currentDisplay);
|
||||
int precision = 0;
|
||||
if (abs(returnValue) < OPTIMALDECIMALALLOWED)
|
||||
{
|
||||
precision = MAXIMUMDIGITSALLOWED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fewer digits are needed following the decimal if the number is large,
|
||||
// we calculate the number of decimals necessary based on the number of digits in the integer part.
|
||||
precision = max(0, max(OPTIMALDIGITSALLOWED, min(MAXIMUMDIGITSALLOWED, currentNumberSignificantDigits)) - numPreDecimal);
|
||||
}
|
||||
|
||||
m_returnDisplay = RoundSignificantDigits(returnValue, precision);
|
||||
TrimTrailingZeros(m_returnDisplay);
|
||||
}
|
||||
m_returnDisplay = returnString;
|
||||
TrimString(m_returnDisplay);
|
||||
m_returnHasDecimal = (m_returnDisplay.find(L'.') != wstring::npos);
|
||||
}
|
||||
m_returnHasDecimal = (m_returnDisplay.find(L'.') != m_returnDisplay.npos);
|
||||
}
|
||||
UpdateViewModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trims out any trailing zeros or decimals in the given input string
|
||||
/// </summary>
|
||||
/// <param name="input">wstring to trim</param>
|
||||
void UnitConverter::TrimString(wstring& returnString)
|
||||
{
|
||||
if (returnString.find(L'.') == m_returnDisplay.npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wstring::iterator iter;
|
||||
for (iter = returnString.end() - 1;; iter--)
|
||||
{
|
||||
if (*iter != L'0')
|
||||
{
|
||||
returnString.erase(iter + 1, returnString.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*(returnString.end() - 1) == L'.')
|
||||
{
|
||||
returnString.erase(returnString.end() - 1, returnString.end());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the given double to the given number of significant digits
|
||||
/// </summary>
|
||||
/// <param name="num">input double</param>
|
||||
/// <param name="numSignificant">int number of significant digits to round to</param>
|
||||
wstring UnitConverter::RoundSignificant(double num, int numSignificant)
|
||||
{
|
||||
wstringstream out(wstringstream::out);
|
||||
out << fixed;
|
||||
out.precision(numSignificant);
|
||||
out << num;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void UnitConverter::UpdateCurrencySymbols()
|
||||
{
|
||||
if (m_currencyDataLoader != nullptr && m_vmCurrencyCallback != nullptr)
|
||||
|
@@ -279,9 +279,7 @@ namespace UnitConversionManager
|
||||
double Convert(double value, ConversionData conversionData);
|
||||
std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested();
|
||||
void ClearValues();
|
||||
void TrimString(std::wstring& input);
|
||||
void InitializeSelectedUnits();
|
||||
std::wstring RoundSignificant(double num, int numSignificant);
|
||||
Category StringToCategory(const std::wstring& w);
|
||||
std::wstring CategoryToString(const Category& c, const wchar_t* delimiter);
|
||||
std::wstring UnitToString(const Unit& u, const wchar_t* delimiter);
|
||||
|
@@ -20,3 +20,5 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <winerror.h>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
|
Reference in New Issue
Block a user