From 770f014bfc0d2d5d60ef13d15e247733c66ba632 Mon Sep 17 00:00:00 2001 From: uhliksk Date: Thu, 14 Mar 2019 04:26:49 +0100 Subject: [PATCH] Fix wrong results after pow and sqrt --- src/CalcManager/Ratpack/exp.cpp | 27 +++++++++++++++++- .../CalculatorManagerTest.cpp | 28 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/CalcManager/Ratpack/exp.cpp b/src/CalcManager/Ratpack/exp.cpp index 97d02c6b..b891c11d 100644 --- a/src/CalcManager/Ratpack/exp.cpp +++ b/src/CalcManager/Ratpack/exp.cpp @@ -297,7 +297,7 @@ void powrat(PRAT *px, PRAT y, uint32_t radix, int32_t precision) } } -void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precision) +void powratNumeratorDenominatorPartial(PRAT *px, PRAT y, uint32_t radix, int32_t precision) { // Prepare rationals PRAT yNumerator = nullptr; @@ -392,6 +392,31 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis destroyrat(pxPow); } +void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precision) +{ + // We need px as simple as possible + gcdrat(px, precision); + + // Prepare rationals + PRAT pxNumerator = nullptr; + PRAT pxDenominator = nullptr; + DUPRAT(pxNumerator, rat_zero); // pxNumerator->pq is 1 one + DUPRAT(pxDenominator, rat_zero); // pxDenominator->pq is 1 one + DUPNUM(pxNumerator->pp, (*px)->pp); + DUPNUM(pxDenominator->pp, (*px)->pq); + + // Calculate pow for Numerator and Denominator separately + powratNumeratorDenominatorPartial(&pxNumerator, y, radix, precision); + powratNumeratorDenominatorPartial(&pxDenominator, y, radix, precision); + + // Combine results back to px + DUPRAT(*px, pxNumerator); + divrat(px, pxDenominator, precision); + + destroyrat(pxNumerator); + destroyrat(pxDenominator); +} + //--------------------------------------------------------------------------- // // FUNCTION: powratcomp diff --git a/src/CalculatorUnitTests/CalculatorManagerTest.cpp b/src/CalculatorUnitTests/CalculatorManagerTest.cpp index cdf8a6f2..4113027b 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() @@ -611,6 +628,17 @@ namespace CalculatorManagerTest Command::CommandPNT, Command::Command2, Command::Command3, Command::Command4, Command::Command5, Command::Command6, Command::CommandADD, Command::CommandNULL }; TestDriver::Test(L"17.161687912241792074207286679393", L"10 ^ 1.23456 + ", commands22, true, true); + + Command commands23[] = { Command::CommandOPENP, Command::Command1, Command::CommandDIV, + Command::Command9, Command::CommandCLOSEP, Command::CommandSQRT, Command::CommandSUB, + Command::Command1, Command::CommandDIV, Command::Command3, Command::CommandADD, Command::CommandNULL }; + TestDriver::Test(L"0", L"\x221A(1 \x00F7 9) - 1 \x00F7 3 + ", commands23, true, true); + + Command commands24[] = { Command::CommandOPENP, Command::Command2, Command::Command7, + Command::CommandDIV, Command::Command1, Command::Command2, Command::CommandCLOSEP, + Command::CommandSQRT, Command::CommandSUB, Command::Command1, Command::CommandPNT, Command::Command5, + Command::CommandADD, Command::CommandNULL }; + TestDriver::Test(L"0", L"\x221A(27 \x00F7 12) - 1.5 + ", commands24, true, true); } void CalculatorManagerTest::CalculatorManagerTestScientificParenthesis()