From 8d02fb828f69cc83ba89e59aa421f4346217a5d8 Mon Sep 17 00:00:00 2001 From: uhliksk Date: Tue, 22 Sep 2020 23:29:48 +0200 Subject: [PATCH] Code cleanup and description --- src/CalcManager/Ratpack/exp.cpp | 15 +++++++++++---- src/CalcManager/Ratpack/rat.cpp | 22 +++++++++++----------- src/CalcManager/Ratpack/ratpak.h | 1 + 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/CalcManager/Ratpack/exp.cpp b/src/CalcManager/Ratpack/exp.cpp index 183dd877..af191638 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 powratNumeratorDenominatorPartial(PRAT *px, PRAT y, uint32_t radix, int32_t precision) +void powratPowerOfPowers(_Inout_ PRAT* px, PRAT y, uint32_t radix, int32_t precision) { // Prepare rationals PRAT yNumerator = nullptr; @@ -392,8 +392,15 @@ void powratNumeratorDenominatorPartial(PRAT *px, PRAT y, uint32_t radix, int32_t destroyrat(pxPow); } -void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precision) +void powratNumeratorDenominator(_Inout_ PRAT* px, PRAT y, uint32_t radix, int32_t precision) { + // To avoid rounding calculate power of numerator and denominator separately and divide the result: + // px ^ py == (xNum ^ py) / (xDenom ^ py) + // In powratPowerOfPowers the following rule is applied: + // px ^ py == px ^ (yNum/yDenom) == px ^ yNum ^ (1/yDenom) + // Final expression is then: + // px ^ py == (xNum ^ yNum ^ (1/yDenom)) / (xDenom ^ yNum ^ (1/yDenom)) + // We need px as simple as possible gcdrat(px, precision); @@ -406,8 +413,8 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis DUPNUM(pxDenominator->pp, (*px)->pq); // Calculate pow for Numerator and Denominator separately - powratNumeratorDenominatorPartial(&pxNumerator, y, radix, precision); - powratNumeratorDenominatorPartial(&pxDenominator, y, radix, precision); + powratPowerOfPowers(&pxNumerator, y, radix, precision); + powratPowerOfPowers(&pxDenominator, y, radix, precision); // Combine results back to px DUPRAT(*px, pxNumerator); diff --git a/src/CalcManager/Ratpack/rat.cpp b/src/CalcManager/Ratpack/rat.cpp index 8ad39853..acc9fc65 100644 --- a/src/CalcManager/Ratpack/rat.cpp +++ b/src/CalcManager/Ratpack/rat.cpp @@ -38,22 +38,22 @@ using namespace std; // //----------------------------------------------------------------------------- -void gcdrat( PRAT *pa, int32_t precision) +void gcdrat(PRAT* pa, int32_t precision) { - PNUMBER pgcd= nullptr; - PRAT a= nullptr; + PNUMBER pgcd = nullptr; + PRAT a = nullptr; - DUPRAT(a,*pa); - pgcd = gcd( a->pp, a->pq ); + DUPRAT(a, *pa); + pgcd = gcd(a->pp, a->pq); - if ( !zernum( pgcd ) ) - { - divnumx( &(a->pp), pgcd, precision); - divnumx( &(a->pq), pgcd, precision); - } + if (!zernum(pgcd)) + { + divnumx(&(a->pp), pgcd, precision); + divnumx(&(a->pq), pgcd, precision); + } - destroynum( pgcd ); + destroynum(pgcd); RENORMALIZE(a); diff --git a/src/CalcManager/Ratpack/ratpak.h b/src/CalcManager/Ratpack/ratpak.h index 3ae06734..9f72f873 100644 --- a/src/CalcManager/Ratpack/ratpak.h +++ b/src/CalcManager/Ratpack/ratpak.h @@ -434,6 +434,7 @@ extern void numpowlongx( _Inout_ PNUMBER *proot, long power ); extern void orrat( _Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void powrat( _Inout_ PRAT *pa, _In_ PRAT b , uint32_t radix, int32_t precision); extern void powratNumeratorDenominator(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); +extern void powratPowerOfPowers(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void powratcomp(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void ratpowlong( _Inout_ PRAT *proot, long power, int32_t precision); extern void remnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix);