mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-22 14:13:30 -07:00
Fix automatic scientific notation
This commit is contained in:
parent
af41a183a7
commit
abd556f476
9 changed files with 53 additions and 7 deletions
|
@ -392,6 +392,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
||||||
m_nPrevOpCode = 0;
|
m_nPrevOpCode = 0;
|
||||||
m_bNoPrevEqu = true;
|
m_bNoPrevEqu = true;
|
||||||
|
|
||||||
|
m_nFE = m_nDefaultFE;
|
||||||
|
|
||||||
/* clear the parenthesis status box indicator, this will not be
|
/* clear the parenthesis status box indicator, this will not be
|
||||||
cleared for CENTR */
|
cleared for CENTR */
|
||||||
|
@ -760,7 +761,14 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
||||||
|
|
||||||
case IDC_FE:
|
case IDC_FE:
|
||||||
// Toggle exponential notation display.
|
// Toggle exponential notation display.
|
||||||
m_nFE = NUMOBJ_FMT(!(int)m_nFE);
|
if (m_nFE == FMT_SCIENTIFIC)
|
||||||
|
{
|
||||||
|
m_nFE = FMT_FLOAT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_nFE = FMT_SCIENTIFIC;
|
||||||
|
}
|
||||||
DisplayNum();
|
DisplayNum();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ namespace CalculationManager
|
||||||
m_currentCalculatorEngine->ProcessCommand(IDC_CLEAR);
|
m_currentCalculatorEngine->ProcessCommand(IDC_CLEAR);
|
||||||
m_currentCalculatorEngine->ChangePrecision(static_cast<int>(CalculatorPrecision::StandardModePrecision));
|
m_currentCalculatorEngine->ChangePrecision(static_cast<int>(CalculatorPrecision::StandardModePrecision));
|
||||||
UpdateMaxIntDigits();
|
UpdateMaxIntDigits();
|
||||||
|
m_currentCalculatorEngine->ChangeFormat(FMT_FLOAT);
|
||||||
m_pHistory = m_pStdHistory.get();
|
m_pHistory = m_pStdHistory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +191,7 @@ namespace CalculationManager
|
||||||
m_currentCalculatorEngine->ProcessCommand(IDC_DEC);
|
m_currentCalculatorEngine->ProcessCommand(IDC_DEC);
|
||||||
m_currentCalculatorEngine->ProcessCommand(IDC_CLEAR);
|
m_currentCalculatorEngine->ProcessCommand(IDC_CLEAR);
|
||||||
m_currentCalculatorEngine->ChangePrecision(static_cast<int>(CalculatorPrecision::ScientificModePrecision));
|
m_currentCalculatorEngine->ChangePrecision(static_cast<int>(CalculatorPrecision::ScientificModePrecision));
|
||||||
|
m_currentCalculatorEngine->ChangeFormat(FMT_AUTOSCIENTIFIC);
|
||||||
m_pHistory = m_pSciHistory.get();
|
m_pHistory = m_pSciHistory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ public:
|
||||||
int GetCurrentRadix();
|
int GetCurrentRadix();
|
||||||
std::wstring GetCurrentResultForRadix(uint32_t radix, int32_t precision);
|
std::wstring GetCurrentResultForRadix(uint32_t radix, int32_t precision);
|
||||||
void ChangePrecision(int32_t precision) { m_precision = precision; ChangeConstants(m_radix, precision); }
|
void ChangePrecision(int32_t precision) { m_precision = precision; ChangeConstants(m_radix, precision); }
|
||||||
|
void ChangeFormat(eNUMOBJ_FMT format) { m_nFE = format; m_nDefaultFE = format; }
|
||||||
std::wstring GroupDigitsPerRadix(std::wstring_view numberString, uint32_t radix);
|
std::wstring GroupDigitsPerRadix(std::wstring_view numberString, uint32_t radix);
|
||||||
std::wstring GetStringForDisplay(CalcEngine::Rational const& rat, uint32_t radix);
|
std::wstring GetStringForDisplay(CalcEngine::Rational const& rat, uint32_t radix);
|
||||||
void UpdateMaxIntDigits();
|
void UpdateMaxIntDigits();
|
||||||
|
@ -89,6 +90,7 @@ private:
|
||||||
bool m_bSetCalcState; // Flag for setting the engine result state
|
bool m_bSetCalcState; // Flag for setting the engine result state
|
||||||
CalcEngine::CalcInput m_input; // Global calc input object for decimal strings
|
CalcEngine::CalcInput m_input; // Global calc input object for decimal strings
|
||||||
eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */
|
eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */
|
||||||
|
eNUMOBJ_FMT m_nDefaultFE; /* Default scientific notation conversion flag. */
|
||||||
CalcEngine::Rational m_maxTrigonometricNum;
|
CalcEngine::Rational m_maxTrigonometricNum;
|
||||||
std::unique_ptr<CalcEngine::Rational> m_memoryValue; // Current memory value.
|
std::unique_ptr<CalcEngine::Rational> m_memoryValue; // Current memory value.
|
||||||
|
|
||||||
|
|
|
@ -1121,7 +1121,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
|
||||||
int32_t exponent = pnum->exp + length; // Actual number of digits to the left of decimal
|
int32_t exponent = pnum->exp + length; // Actual number of digits to the left of decimal
|
||||||
|
|
||||||
int32_t oldFormat = format;
|
int32_t oldFormat = format;
|
||||||
if (exponent > precision && format == FMT_FLOAT)
|
if (exponent > precision && format == FMT_AUTOSCIENTIFIC)
|
||||||
{
|
{
|
||||||
// Force scientific mode to prevent user from assuming 33rd digit is exact.
|
// Force scientific mode to prevent user from assuming 33rd digit is exact.
|
||||||
format = FMT_SCIENTIFIC;
|
format = FMT_SCIENTIFIC;
|
||||||
|
@ -1144,7 +1144,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
|
||||||
divnum(&round, num_two, radix, precision);
|
divnum(&round, num_two, radix, precision);
|
||||||
|
|
||||||
// Make round number exponent one below the LSD for the number.
|
// Make round number exponent one below the LSD for the number.
|
||||||
if (exponent > 0 || format == FMT_FLOAT)
|
if (exponent > 0 || format == FMT_FLOAT || format == FMT_AUTOSCIENTIFIC)
|
||||||
{
|
{
|
||||||
round->exp = pnum->exp + pnum->cdigit - round->cdigit - precision;
|
round->exp = pnum->exp + pnum->cdigit - round->cdigit - precision;
|
||||||
}
|
}
|
||||||
|
@ -1157,12 +1157,12 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
|
||||||
round->sign = pnum->sign;
|
round->sign = pnum->sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == FMT_FLOAT)
|
if (format == FMT_FLOAT || format == FMT_AUTOSCIENTIFIC)
|
||||||
{
|
{
|
||||||
// Figure out if the exponent will fill more space than the non-exponent 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 || format == FMT_FLOAT && round != nullptr)
|
||||||
{
|
{
|
||||||
round->exp -= exponent;
|
round->exp -= exponent;
|
||||||
length = precision + exponent;
|
length = precision + exponent;
|
||||||
|
|
|
@ -28,7 +28,8 @@ typedef uint32_t MANTTYPE;
|
||||||
typedef uint64_t TWO_MANTTYPE;
|
typedef uint64_t TWO_MANTTYPE;
|
||||||
|
|
||||||
enum eNUMOBJ_FMT {
|
enum eNUMOBJ_FMT {
|
||||||
FMT_FLOAT, // returns floating point, or exponential if number is too big
|
FMT_FLOAT, // always returns floating point
|
||||||
|
FMT_AUTOSCIENTIFIC,// returns floating point, or exponential if number is too big
|
||||||
FMT_SCIENTIFIC, // always returns scientific notation
|
FMT_SCIENTIFIC, // always returns scientific notation
|
||||||
FMT_ENGINEERING // always returns engineering notation such that exponent is a multiple of 3
|
FMT_ENGINEERING // always returns engineering notation such that exponent is a multiple of 3
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
|
||||||
m_MemorizedNumbers(ref new Vector<MemoryItemViewModel^>()),
|
m_MemorizedNumbers(ref new Vector<MemoryItemViewModel^>()),
|
||||||
m_IsMemoryEmpty(true),
|
m_IsMemoryEmpty(true),
|
||||||
m_IsFToEChecked(false),
|
m_IsFToEChecked(false),
|
||||||
|
m_IsFToEAuto(false),
|
||||||
m_isShiftChecked(false),
|
m_isShiftChecked(false),
|
||||||
m_IsShiftProgrammerChecked(false),
|
m_IsShiftProgrammerChecked(false),
|
||||||
m_IsQwordEnabled(true),
|
m_IsQwordEnabled(true),
|
||||||
|
@ -203,6 +204,21 @@ void StandardCalculatorViewModel::SetPrimaryDisplay(_In_ wstring const &displayS
|
||||||
|
|
||||||
DisplayValue = localizedDisplayStringValue;
|
DisplayValue = localizedDisplayStringValue;
|
||||||
|
|
||||||
|
if (!IsFToEAuto && !IsFToEChecked && displayStringValue.find(L"e") != std::wstring::npos)
|
||||||
|
{
|
||||||
|
IsFToEAuto = true;
|
||||||
|
IsFToEChecked = true;
|
||||||
|
}
|
||||||
|
else if (IsFToEAuto && IsFToEChecked && displayStringValue.find(L"e") == std::wstring::npos)
|
||||||
|
{
|
||||||
|
IsFToEChecked = false;
|
||||||
|
IsFToEAuto = false;
|
||||||
|
}
|
||||||
|
else if (IsFToEAuto && !IsFToEChecked)
|
||||||
|
{
|
||||||
|
IsFToEAuto = false;
|
||||||
|
}
|
||||||
|
|
||||||
IsInError = isError;
|
IsInError = isError;
|
||||||
|
|
||||||
if (IsProgrammer)
|
if (IsProgrammer)
|
||||||
|
@ -1167,6 +1183,7 @@ Array<unsigned char>^ StandardCalculatorViewModel::Serialize()
|
||||||
DataWriter^ writer = ref new DataWriter();
|
DataWriter^ writer = ref new DataWriter();
|
||||||
writer->WriteUInt32(static_cast<UINT32>(m_CurrentAngleType));
|
writer->WriteUInt32(static_cast<UINT32>(m_CurrentAngleType));
|
||||||
writer->WriteBoolean(IsFToEChecked);
|
writer->WriteBoolean(IsFToEChecked);
|
||||||
|
writer->WriteBoolean(IsFToEAuto);
|
||||||
writer->WriteBoolean(IsCurrentViewPinned);
|
writer->WriteBoolean(IsCurrentViewPinned);
|
||||||
writer->WriteUInt32(static_cast<UINT32>(m_standardCalculatorManager.SerializeSavedDegreeMode()));
|
writer->WriteUInt32(static_cast<UINT32>(m_standardCalculatorManager.SerializeSavedDegreeMode()));
|
||||||
|
|
||||||
|
@ -1225,6 +1242,7 @@ void StandardCalculatorViewModel::Deserialize(Array<unsigned char>^ state)
|
||||||
m_CurrentAngleType = ConvertIntegerToNumbersAndOperatorsEnum(reader->ReadUInt32());
|
m_CurrentAngleType = ConvertIntegerToNumbersAndOperatorsEnum(reader->ReadUInt32());
|
||||||
|
|
||||||
IsFToEChecked = reader->ReadBoolean();
|
IsFToEChecked = reader->ReadBoolean();
|
||||||
|
IsFToEAuto = reader->ReadBoolean();
|
||||||
IsCurrentViewPinned = reader->ReadBoolean();
|
IsCurrentViewPinned = reader->ReadBoolean();
|
||||||
Command serializedDegreeMode = static_cast<Command>(reader->ReadUInt32());
|
Command serializedDegreeMode = static_cast<Command>(reader->ReadUInt32());
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ namespace CalculatorApp
|
||||||
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty);
|
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty);
|
||||||
OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked);
|
OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked);
|
||||||
OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled);
|
OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled);
|
||||||
|
OBSERVABLE_PROPERTY_RW(bool, IsFToEAuto);
|
||||||
OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked);
|
OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked);
|
||||||
OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled);
|
OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled);
|
||||||
OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationResultAutomationName);
|
OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationResultAutomationName);
|
||||||
|
|
|
@ -43,7 +43,20 @@ void CalculatorScientificAngleButtons::HypButton_Toggled(_In_ Object^ sender, _I
|
||||||
void CalculatorScientificAngleButtons::FToEButton_Toggled(_In_ Object^ sender,_In_ RoutedEventArgs^ e)
|
void CalculatorScientificAngleButtons::FToEButton_Toggled(_In_ Object^ sender,_In_ RoutedEventArgs^ e)
|
||||||
{
|
{
|
||||||
auto viewModel = safe_cast<StandardCalculatorViewModel^>(this->DataContext);
|
auto viewModel = safe_cast<StandardCalculatorViewModel^>(this->DataContext);
|
||||||
viewModel->FtoEButtonToggled();
|
if (!viewModel->IsFToEAuto)
|
||||||
|
{
|
||||||
|
viewModel->FtoEButtonToggled();
|
||||||
|
}
|
||||||
|
else if (viewModel->IsFToEAuto && !viewModel->IsFToEChecked)
|
||||||
|
{
|
||||||
|
std::wstring displayValue(viewModel->DisplayValue->Data());
|
||||||
|
if (displayValue.find(L"e") != std::wstring::npos)
|
||||||
|
{
|
||||||
|
viewModel->IsFToEAuto = false;
|
||||||
|
viewModel->FtoEButtonToggled();
|
||||||
|
viewModel->FtoEButtonToggled();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalculatorApp::CalculatorScientificAngleButtons::OnAngleButtonPressed(_In_ Object^ commandParameter)
|
void CalculatorApp::CalculatorScientificAngleButtons::OnAngleButtonPressed(_In_ Object^ commandParameter)
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace CalculatorFunctionalTests
|
||||||
m_standardViewModel->SetExpressionDisplay(e->GetTokens(), e->GetCommands());
|
m_standardViewModel->SetExpressionDisplay(e->GetTokens(), e->GetCommands());
|
||||||
m_standardViewModel->SetPrimaryDisplay(e->Result->Data(), false/*IsError*/);
|
m_standardViewModel->SetPrimaryDisplay(e->Result->Data(), false/*IsError*/);
|
||||||
m_standardViewModel->IsFToEEnabled = false;
|
m_standardViewModel->IsFToEEnabled = false;
|
||||||
|
m_standardViewModel->IsFToEAuto = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddSingleHistoryItem()
|
void AddSingleHistoryItem()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue