@@ -3671,16 +3671,15 @@ namespace BlazesRusCode
36713671 }
36723672 else // Returns a positive value(http://www.netlib.org/cephes/qlibdoc.html#qlog)
36733673 {// Increasing iterations brings closer to accurate result(Larger numbers need more iterations to get accurate level of result)
3674- // MediumDec W = (value - 1) / (value + 1);
3675- MediumDec TotalRes = (value - 1 ) / (value + 1 );// W;
3674+ MediumDec TotalRes = (value - 1 ) / (value + 1 );
36763675 MediumDec LastPow = TotalRes;
36773676 MediumDec WSquared = TotalRes * TotalRes;
36783677 MediumDec AddRes;
36793678 int WPow = 3 ;
36803679 do
36813680 {
36823681 LastPow *= WSquared;
3683- AddRes = LastPow / WPow;// MediumDec::PowRef(W, WPow) / WPow;
3682+ AddRes = LastPow / WPow;
36843683 TotalRes += AddRes; WPow += 2 ;
36853684 } while (AddRes > MediumDec::JustAboveZero);
36863685 return TotalRes * 2 ;
@@ -3742,16 +3741,15 @@ namespace BlazesRusCode
37423741 }
37433742 else // Returns a positive value(http://www.netlib.org/cephes/qlibdoc.html#qlog)
37443743 {// Increasing iterations brings closer to accurate result(Larger numbers need more iterations to get accurate level of result)
3745- // MediumDec W = (value - 1) / (value + 1);
3746- MediumDec TotalRes = (value - 1 ) / (value + 1 );// W;
3744+ MediumDec TotalRes = (value - 1 ) / (value + 1 );
37473745 MediumDec LastPow = TotalRes;
37483746 MediumDec WSquared = TotalRes * TotalRes;
37493747 MediumDec AddRes;
37503748 int WPow = 3 ;
37513749 do
37523750 {
37533751 LastPow *= WSquared;
3754- AddRes = LastPow / WPow;// MediumDec::PowRef(W, WPow) / WPow;
3752+ AddRes = LastPow / WPow;
37553753 TotalRes += AddRes; WPow += 2 ;
37563754 } while (AddRes > MediumDec::JustAboveZero);
37573755 return TotalRes * 2 ;
@@ -3809,13 +3807,15 @@ namespace BlazesRusCode
38093807 }
38103808 else // Returns a positive value(http://www.netlib.org/cephes/qlibdoc.html#qlog)
38113809 {
3812- MediumDec W = (value - 1 ) / (value + 1 );
3813- MediumDec TotalRes = W;
3810+ MediumDec TotalRes = (value - 1 ) / (value + 1 );
3811+ MediumDec LastPow = TotalRes;
3812+ MediumDec WSquared = TotalRes * TotalRes;
38143813 MediumDec AddRes;
38153814 int WPow = 3 ;
38163815 do
38173816 {
3818- AddRes = MediumDec::PowRef (W, WPow) / WPow;
3817+ LastPow *= WSquared;
3818+ AddRes = LastPow / WPow;
38193819 TotalRes += AddRes; WPow += 2 ;
38203820 } while (AddRes > MediumDec::JustAboveZero);
38213821 return TotalRes * MediumDec::HalfLN10Mult;// Gives more accurate answer than attempting to divide by Ln10
@@ -3844,7 +3844,111 @@ namespace BlazesRusCode
38443844 }
38453845 else // Returns a positive value(http://www.netlib.org/cephes/qlibdoc.html#qlog)
38463846 {
3847- MediumDec W = MediumDec ((value - 1 ), 0 ) / MediumDec ((value + 1 ), 0 );
3847+ MediumDec TotalRes = MediumDec ((value - 1 ), 0 ) / MediumDec ((value + 1 ), 0 );
3848+ MediumDec LastPow = TotalRes;
3849+ MediumDec WSquared = TotalRes * TotalRes;
3850+ MediumDec AddRes;
3851+ int WPow = 3 ;
3852+ do
3853+ {
3854+ LastPow *= WSquared;
3855+ AddRes = LastPow / WPow;
3856+ TotalRes += AddRes; WPow += 2 ;
3857+ } while (AddRes > MediumDec::JustAboveZero);
3858+ return TotalRes * MediumDec::HalfLN10Mult;// Gives more accurate answer than attempting to divide by Ln10
3859+ }
3860+ }
3861+
3862+ // / <summary>
3863+ // / Log with Base of BaseVal of Value
3864+ // / Based on http://home.windstream.net/okrebs/page57.html
3865+ // / </summary>
3866+ // / <param name="value">The value.</param>
3867+ // / <param name="baseVal">The base of Log</param>
3868+ // / <returns>MediumDec</returns>
3869+ static MediumDec Log (MediumDec value, MediumDec baseVal)
3870+ {
3871+ if (value == MediumDec::One)
3872+ return MediumDec::Zero;
3873+ return Log10 (value) / Log10 (baseVal);
3874+ }
3875+
3876+ // / <summary>
3877+ // / Log with Base of BaseVal of Value
3878+ // / Based on http://home.windstream.net/okrebs/page57.html
3879+ // / </summary>
3880+ // / <param name="Value">The value.</param>
3881+ // / <param name="BaseVal">The base of Log</param>
3882+ // / <returns>MediumDec</returns>
3883+ static MediumDec Log (MediumDec value, int baseVal)
3884+ {
3885+ if (value == MediumDec::One)
3886+ return MediumDec::Zero;
3887+ // Calculate Base log first
3888+ MediumDec baseTotalRes;
3889+ bool lnMultLog = true ;
3890+ if (baseVal % 10 == 0 )
3891+ {
3892+ for (int index = 1 ; index < 9 ; ++index)
3893+ {
3894+ if (baseVal == BlazesRusCode::VariableConversionFunctions::PowerOfTens[index])
3895+ {
3896+ baseTotalRes = MediumDec (index, 0 );
3897+ break ;
3898+ }
3899+ }
3900+ baseTotalRes = MediumDec (9 , 0 ); lnMultLog = false ;
3901+ }
3902+ else // Returns a positive baseVal(http://www.netlib.org/cephes/qlibdoc.html#qlog)
3903+ {
3904+ baseTotalRes = MediumDec ((baseVal - 1 ), 0 ) / MediumDec ((baseVal + 1 ), 0 );
3905+ MediumDec baseLastPow = baseTotalRes;
3906+ MediumDec baseWSquared = baseTotalRes * baseTotalRes;
3907+ MediumDec baseAddRes;
3908+ int baseWPow = 3 ;
3909+ do
3910+ {
3911+ baseLastPow *= baseWSquared;
3912+ baseAddRes = baseLastPow / baseWPow;
3913+ baseTotalRes += baseAddRes; baseWPow += 2 ;
3914+ } while (baseAddRes > MediumDec::JustAboveZero);
3915+ }
3916+
3917+ // Now calculate other log
3918+ if (value.DecimalHalf01 == 0 && value.IntValue % 10 == 0 )
3919+ {
3920+ for (int index = 1 ; index < 9 ; ++index)
3921+ {
3922+ if (value == BlazesRusCode::VariableConversionFunctions::PowerOfTens[index])
3923+ return lnMultLog ? MediumDec (index, 0 ) / (baseTotalRes * MediumDec::HalfLN10Mult): MediumDec (index, 0 )/ baseTotalRes;
3924+ }
3925+ return lnMultLog? MediumDec (9 , 0 ) / (baseTotalRes*MediumDec::HalfLN10Mult):MediumDec (9 , 0 )/baseTotalRes;
3926+ }
3927+ if (value.IntValue < 2 )// Threshold between 0 and 2 based on Taylor code series from https://stackoverflow.com/questions/26820871/c-program-which-calculates-ln-for-a-given-variable-x-without-using-any-ready-f
3928+ {// This section gives accurate answer for values between 1 & 2
3929+ MediumDec threshold = MediumDec::FiveBillionth;
3930+ MediumDec base = value - 1 ; // Base of the numerator; exponent will be explicit
3931+ int den = 1 ; // Denominator of the nth term
3932+ bool posSign = true ; // Used to swap the sign of each term
3933+ MediumDec term = base; // First term
3934+ MediumDec prev = 0 ; // Previous sum
3935+ MediumDec result = term; // Kick it off
3936+
3937+ while (MediumDec::Abs (prev - result) > threshold) {
3938+ den++;
3939+ posSign = !posSign;
3940+ term *= base;
3941+ prev = result;
3942+ if (posSign)
3943+ result += term / den;
3944+ else
3945+ result -= term / den;
3946+ }
3947+ return lnMultLog? result/baseTotalRes:(result*2 )/ baseTotalRes;
3948+ }
3949+ else // Returns a positive value(http://www.netlib.org/cephes/qlibdoc.html#qlog)
3950+ {
3951+ MediumDec W = (value - 1 ) / (value + 1 );
38483952 MediumDec TotalRes = W;
38493953 MediumDec AddRes;
38503954 int WPow = 3 ;
@@ -3853,8 +3957,9 @@ namespace BlazesRusCode
38533957 AddRes = MediumDec::PowRef (W, WPow) / WPow;
38543958 TotalRes += AddRes; WPow += 2 ;
38553959 } while (AddRes > MediumDec::JustAboveZero);
3856- return TotalRes * MediumDec::HalfLN10Mult; // Gives more accurate answer than attempting to divide by Ln10
3960+ return lnMultLog? TotalRes/baseTotalRes:(TotalRes * MediumDec::HalfLN10Mult)/ baseTotalRes;
38573961 }
3962+ // return Log10(Value) / Log10(BaseVal);
38583963 }
38593964
38603965 #pragma endregion Math Etc Functions
0 commit comments