diff --git a/src/CalcManager/Ratpack/exp.cpp b/src/CalcManager/Ratpack/exp.cpp index 97d02c6b..a229166f 100644 --- a/src/CalcManager/Ratpack/exp.cpp +++ b/src/CalcManager/Ratpack/exp.cpp @@ -342,11 +342,32 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis DUPRAT(originalResult, pxPow); powratcomp(&originalResult, oneoveryDenom, radix, precision); + // ################################## + // Find number of digits after decimal point + // and prepare multiplier for rounding + // ################################## + PRAT resultMultiplier = nullptr; + PRAT resultDigits = nullptr; + PNUMBER numResult = RatToNumber(pxPow, radix, precision); + if (-numResult->exp < precision) + { + DUPRAT(resultDigits, longtorat(-numResult->exp / 2)); + } + else + { + DUPRAT(resultDigits, rat_zero); + } + DUPRAT(resultMultiplier, rat_ten); + powratcomp(&resultMultiplier, resultDigits, radix, precision); + destroyrat(resultDigits); + destroynum(numResult); + // ################################## // Round the originalResult to roundedResult // ################################## PRAT roundedResult = nullptr; DUPRAT(roundedResult, originalResult); + mulrat(&roundedResult, resultMultiplier, precision); if (roundedResult->pp->sign == -1) { subrat(&roundedResult, rat_half, precision); @@ -356,6 +377,8 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis addrat(&roundedResult, rat_half, precision); } intrat(&roundedResult, radix, precision); + divrat(&roundedResult, resultMultiplier, precision); + destroyrat(resultMultiplier); // ################################## // Take the yDenom power of the roundedResult. diff --git a/src/CalculatorUnitTests/CalculatorManagerTest.cpp b/src/CalculatorUnitTests/CalculatorManagerTest.cpp index cdf8a6f2..4267240c 100644 --- a/src/CalculatorUnitTests/CalculatorManagerTest.cpp +++ b/src/CalculatorUnitTests/CalculatorManagerTest.cpp @@ -428,6 +428,23 @@ namespace CalculatorManagerTest Command::CommandSQRT, Command::CommandSUB, Command::Command3, Command::Command2, Command::CommandADD, Command::CommandNULL }; TestDriver::Test(L"0", L"\x221A(1024) - 32 + ", commands22); + + Command commands23[] = { Command::Command2, Command::CommandPNT, Command::Command2, Command::Command5, + Command::CommandSQRT, Command::CommandSUB, Command::Command1, Command::CommandPNT, Command::Command5, + Command::CommandADD, Command::CommandNULL }; + TestDriver::Test(L"0", L"\x221A(2.25) - 1.5 + ", commands23); + + Command commands24[] = { Command::Command8, Command::Command7, Command::Command6, Command::Command5, + Command::Command4, Command::Command3, Command::Command2, Command::Command1, + Command::CommandPNT, Command::Command1, Command::Command2, Command::Command3, Command::Command4, + Command::Command5, Command::Command6, Command::Command7, Command::Command8, + Command::CommandSQR, Command::CommandSQRT, Command::CommandSUB, + Command::Command8, Command::Command7, Command::Command6, Command::Command5, + Command::Command4, Command::Command3, Command::Command2, Command::Command1, + Command::CommandPNT, Command::Command1, Command::Command2, Command::Command3, Command::Command4, + Command::Command5, Command::Command6, Command::Command7, Command::Command8, + Command::CommandADD, Command::CommandNULL }; + TestDriver::Test(L"0", L"\x221A(sqr(87654321.12345678)) - 87654321.12345678 + ", commands24); } void CalculatorManagerTest::CalculatorManagerTestScientific()