diff --git a/src/CalcManager/CEngine/scicomm.cpp b/src/CalcManager/CEngine/scicomm.cpp index f17938bf..564ce752 100644 --- a/src/CalcManager/CEngine/scicomm.cpp +++ b/src/CalcManager/CEngine/scicomm.cpp @@ -392,6 +392,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam) m_nPrevOpCode = 0; m_bNoPrevEqu = true; + m_nFE = m_nDefaultFE; /* clear the parenthesis status box indicator, this will not be cleared for CENTR */ @@ -760,7 +761,14 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam) case IDC_FE: // 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(); break; diff --git a/src/CalcManager/CalculatorManager.cpp b/src/CalcManager/CalculatorManager.cpp index b4b4dfaf..eb888fb3 100644 --- a/src/CalcManager/CalculatorManager.cpp +++ b/src/CalcManager/CalculatorManager.cpp @@ -173,6 +173,7 @@ namespace CalculationManager m_currentCalculatorEngine->ProcessCommand(IDC_CLEAR); m_currentCalculatorEngine->ChangePrecision(static_cast(CalculatorPrecision::StandardModePrecision)); UpdateMaxIntDigits(); + m_currentCalculatorEngine->ChangeFormat(FMT_FLOAT); m_pHistory = m_pStdHistory.get(); } @@ -190,6 +191,7 @@ namespace CalculationManager m_currentCalculatorEngine->ProcessCommand(IDC_DEC); m_currentCalculatorEngine->ProcessCommand(IDC_CLEAR); m_currentCalculatorEngine->ChangePrecision(static_cast(CalculatorPrecision::ScientificModePrecision)); + m_currentCalculatorEngine->ChangeFormat(FMT_AUTOSCIENTIFIC); m_pHistory = m_pSciHistory.get(); } diff --git a/src/CalcManager/Header Files/CalcEngine.h b/src/CalcManager/Header Files/CalcEngine.h index 0ad8252f..f5ff9161 100644 --- a/src/CalcManager/Header Files/CalcEngine.h +++ b/src/CalcManager/Header Files/CalcEngine.h @@ -64,6 +64,7 @@ public: int GetCurrentRadix(); std::wstring GetCurrentResultForRadix(uint32_t radix, int32_t 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 GetStringForDisplay(CalcEngine::Rational const& rat, uint32_t radix); void UpdateMaxIntDigits(); @@ -89,6 +90,7 @@ private: bool m_bSetCalcState; // Flag for setting the engine result state CalcEngine::CalcInput m_input; // Global calc input object for decimal strings eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */ + eNUMOBJ_FMT m_nDefaultFE; /* Default scientific notation conversion flag. */ CalcEngine::Rational m_maxTrigonometricNum; std::unique_ptr m_memoryValue; // Current memory value. diff --git a/src/CalcManager/Ratpack/conv.cpp b/src/CalcManager/Ratpack/conv.cpp index c25d4481..4cfba8ce 100644 --- a/src/CalcManager/Ratpack/conv.cpp +++ b/src/CalcManager/Ratpack/conv.cpp @@ -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 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. format = FMT_SCIENTIFIC; @@ -1144,7 +1144,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_ divnum(&round, num_two, radix, precision); // 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; } @@ -1157,12 +1157,12 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_ 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. 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; length = precision + exponent; diff --git a/src/CalcManager/Ratpack/ratpak.h b/src/CalcManager/Ratpack/ratpak.h index 75ac28de..754a7fd7 100644 --- a/src/CalcManager/Ratpack/ratpak.h +++ b/src/CalcManager/Ratpack/ratpak.h @@ -28,7 +28,8 @@ typedef uint32_t MANTTYPE; typedef uint64_t TWO_MANTTYPE; 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_ENGINEERING // always returns engineering notation such that exponent is a multiple of 3 diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index c01c4789..b7522df8 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -70,6 +70,7 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() : m_MemorizedNumbers(ref new Vector()), m_IsMemoryEmpty(true), m_IsFToEChecked(false), + m_IsFToEAuto(false), m_isShiftChecked(false), m_IsShiftProgrammerChecked(false), m_IsQwordEnabled(true), @@ -203,6 +204,21 @@ void StandardCalculatorViewModel::SetPrimaryDisplay(_In_ wstring const &displayS 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; if (IsProgrammer) @@ -1167,6 +1183,7 @@ Array^ StandardCalculatorViewModel::Serialize() DataWriter^ writer = ref new DataWriter(); writer->WriteUInt32(static_cast(m_CurrentAngleType)); writer->WriteBoolean(IsFToEChecked); + writer->WriteBoolean(IsFToEAuto); writer->WriteBoolean(IsCurrentViewPinned); writer->WriteUInt32(static_cast(m_standardCalculatorManager.SerializeSavedDegreeMode())); @@ -1225,6 +1242,7 @@ void StandardCalculatorViewModel::Deserialize(Array^ state) m_CurrentAngleType = ConvertIntegerToNumbersAndOperatorsEnum(reader->ReadUInt32()); IsFToEChecked = reader->ReadBoolean(); + IsFToEAuto = reader->ReadBoolean(); IsCurrentViewPinned = reader->ReadBoolean(); Command serializedDegreeMode = static_cast(reader->ReadUInt32()); diff --git a/src/CalcViewModel/StandardCalculatorViewModel.h b/src/CalcViewModel/StandardCalculatorViewModel.h index ba6dc82b..54bc66df 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.h +++ b/src/CalcViewModel/StandardCalculatorViewModel.h @@ -66,6 +66,7 @@ namespace CalculatorApp OBSERVABLE_NAMED_PROPERTY_RW(bool, IsMemoryEmpty); OBSERVABLE_PROPERTY_RW(bool, IsFToEChecked); OBSERVABLE_PROPERTY_RW(bool, IsFToEEnabled); + OBSERVABLE_PROPERTY_RW(bool, IsFToEAuto); OBSERVABLE_PROPERTY_RW(bool, IsHyperbolicChecked); OBSERVABLE_PROPERTY_RW(bool, AreHEXButtonsEnabled); OBSERVABLE_PROPERTY_RW(Platform::String^, CalculationResultAutomationName); diff --git a/src/Calculator/Views/CalculatorScientificAngleButtons.xaml.cpp b/src/Calculator/Views/CalculatorScientificAngleButtons.xaml.cpp index 16f0cc5d..19e2eec9 100644 --- a/src/Calculator/Views/CalculatorScientificAngleButtons.xaml.cpp +++ b/src/Calculator/Views/CalculatorScientificAngleButtons.xaml.cpp @@ -43,7 +43,20 @@ void CalculatorScientificAngleButtons::HypButton_Toggled(_In_ Object^ sender, _I void CalculatorScientificAngleButtons::FToEButton_Toggled(_In_ Object^ sender,_In_ RoutedEventArgs^ e) { auto viewModel = safe_cast(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) diff --git a/src/CalculatorUnitTests/HistoryTests.cpp b/src/CalculatorUnitTests/HistoryTests.cpp index 48dfea69..6843f35e 100644 --- a/src/CalculatorUnitTests/HistoryTests.cpp +++ b/src/CalculatorUnitTests/HistoryTests.cpp @@ -77,6 +77,7 @@ namespace CalculatorFunctionalTests m_standardViewModel->SetExpressionDisplay(e->GetTokens(), e->GetCommands()); m_standardViewModel->SetPrimaryDisplay(e->Result->Data(), false/*IsError*/); m_standardViewModel->IsFToEEnabled = false; + m_standardViewModel->IsFToEAuto = false; } void AddSingleHistoryItem()