Skip to content

Commit 194fffe

Browse files
committed
Fixed flipping of decimals for addition/subtraction which fixes most of accuracy of Ln function for values between 0 and 1
1 parent d7c7b14 commit 194fffe

4 files changed

Lines changed: 225 additions & 64 deletions

File tree

ExprFormulaTester/ExprFormulaTester.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,20 +231,22 @@ int main()
231231
std::cout << targetVal.ToString() << " - " << rightVal.ToString() << " = " << altResult.ToString() << " FloatResult:" << floatingVal << std::endl;
232232

233233
std::cout << "---------------Log Tests------------------------------" << std::endl;
234-
targetVal = "0.005";
234+
targetVal = MediumDec::FiveThousandth;
235235
floatingVal = 0.005;
236236
double floatingRes;
237-
for (targetVal = MediumDec::FiveThousandth; targetVal < MediumDec::One; targetVal += MediumDec::FiveThousandth)
237+
do
238238
{
239239
floatingRes = log(floatingVal);
240240
std::cout << "Builtin-Ln(" << floatingVal << ") = " << floatingRes;
241-
floatingRes = BlazesFloatingCode::LnRef(floatingVal);
241+
floatingRes = BlazesFloatingCode::LnRefV2(floatingVal);
242242
std::cout << " Ln(value) =" << floatingRes << std::endl;
243-
floatingVal += 0.005;
244-
altResult = BlazesRusDebug::LnTestRef(floatingVal, targetVal);
245-
std::cout << "(MediumDec)Ln(" << targetVal.ToString() << ")= " << altResult.ToString() << std::endl;
246-
}
247243

244+
altResult = MediumDec::LnRef(targetVal);
245+
std::cout << "(MediumDec)Ln(" << targetVal.ToString() << ")= " << altResult.ToString() << std::endl;
246+
altResult = MediumDec::LnRefV2(targetVal);
247+
std::cout << "(MediumDec)LnV2(" << targetVal.ToString() << ")= " << altResult.ToString() << std::endl;
248+
targetVal += MediumDec::FiveThousandth; floatingVal += 0.005;
249+
} while (targetVal < MediumDec::One);
248250
std::cout << "---------------Testing Formula Code-------------------" << std::endl;
249251
//std::cout << "-------------------------Formula Code Tests---------------------------------" << std::endl;
250252
//IntFormula IntFormTest = "(5+5)^2";
@@ -267,9 +269,8 @@ int main()
267269
//
268270

269271
std::cout << "(MediumDecFormula) "<< AltFormTest.ToString() <<std::endl;
270-
AltFormTest = AltFormTest.SimplifyFormula(ValueDefinitions);
271-
std::cout << " = " << AltFormTest.ToString() << std::endl;
272-
//std::cout << " = " << rootTest.ToString() << std::endl;
272+
//AltFormTest = AltFormTest.SimplifyFormula(ValueDefinitions);
273+
//std::cout << " = " << AltFormTest.ToString() << std::endl;
273274
//AltFormTest = "5.5^(1.5+x)+6x";
274275
//std::cout << "(MediumDecFormula) " << AltFormTest.ToString() << " = " << rootTest.ToString() << std::endl;
275276
//AltFormTest = "5+(5/4)";

GlobalCode/AltNum/AltNumDebug.hpp

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -276,52 +276,47 @@ namespace BlazesRusDebug
276276
//if (value <= 0) {}else//Error if equal or less than 0
277277
if (value==MediumDec::One)
278278
return MediumDec::Zero;
279-
//if (value.IntValue==0)//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
280-
//{
281-
// double fthreshold = 0.000000005;
282-
// double fbase = fvalue - 1; // Base of the numerator; exponent will be explicit
283-
// int den = 2; // Denominator of the nth term
284-
// bool posSign = true; // Used to swap the sign of each term
285-
// double fterm = fbase; // First term
286-
// double fprev; // Previous sum
287-
// double fresult = fterm; // Kick it off
288-
// double fAddRes;
289-
290-
// MediumDec threshold = MediumDec::FiveMillionth;
291-
// MediumDec base = value - 1; // Base of the numerator; exponent will be explicit
292-
// MediumDec term = base; // First term
293-
// MediumDec prev; // Previous sum
294-
// MediumDec result = term; // Kick it off
295-
// MediumDec AddRes;
296-
297-
// do
298-
// {
299-
// posSign = !posSign;
300-
301-
// fterm *= fbase;
302-
// term *= base;
303-
304-
// fprev = fresult;
305-
// prev = result;
279+
if (value.IntValue==0)//Returns a negative number derived from (http://www.netlib.org/cephes/qlibdoc.html#qlog)
280+
{
281+
double fW = (fvalue - 1.0);
282+
MediumDec W = (value - 1);
283+
std::cout << "--Floating W Numerator:" << fW << " vs " << W.ToString() << "--" << std::endl;
284+
double fDenom = (fvalue + 1.0);
285+
fW /= fDenom;//(-0.5)/(1.5)=-1/3
286+
MediumDec Denom = (value + 1);
287+
std::cout << "--Floating W Denom:" << fDenom << " vs " << Denom.ToString() << "--" << std::endl;
288+
W /= Denom;
289+
double fTotalRes = fW;
290+
fW *= -1;
291+
double fLastPow = fW;
292+
double fWSquared = fW * fW;
293+
double fAddRes;
294+
int WPow = 3;
306295

307-
// fAddRes = fterm / den;
308-
// AddRes = term / den;
296+
MediumDec TotalRes = W;
297+
W.SwapNegativeStatus();
298+
MediumDec LastPow = W;
299+
MediumDec WSquared = W * W;
300+
MediumDec AddRes;
301+
std::cout << "--Floating W:" << fW << " vs " << W.ToString() << "--" << std::endl;
302+
do
303+
{
304+
fLastPow *= fWSquared;
305+
LastPow *= WSquared;
306+
//std::cout << "-----Floating LastPow:" << fLastPow << " vs " << LastPow.ToString() << "--" << std::endl;
309307

310-
// if (posSign)
311-
// fresult += fAddRes;
312-
// else
313-
// fresult -= fAddRes;
314-
// if (posSign)
315-
// result += term / den;
316-
// else
317-
// result -= term / den;
308+
fAddRes = fLastPow / WPow;
309+
AddRes = LastPow / WPow;
310+
//std::cout << "-----Floating AddRes:" << fAddRes << " vs " << AddRes.ToString() << "--" << std::endl;
318311

319-
// den++;
320-
// } while (abs(fprev - fresult) > fthreshold);
312+
fTotalRes -= fAddRes;
313+
TotalRes -= AddRes;
321314

322-
// return result;
323-
//} else
324-
if(value.IntValue<2)
315+
WPow += 2;
316+
} while (AddRes > MediumDec::JustAboveZero);//Total Result should be -0.346573590279972654708616060729088284037750067180127627060340004746696810984847357802931663498209344
317+
return TotalRes * 2;//Should result in -0.693147180559
318+
}
319+
else if(value.IntValue==1)
325320
{
326321
MediumDec threshold = MediumDec::FiveMillionth;
327322
MediumDec base = value - 1; // Base of the numerator; exponent will be explicit

GlobalCode/AltNum/FloatingOperations.hpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,76 @@ namespace BlazesFloatingCode
248248
}
249249
}
250250

251+
/// <summary>
252+
/// Natural log (Equivalent to Log_E(value))
253+
/// </summary>
254+
/// <param name="value">The target value.</param>
255+
/// <returns>double</returns>
256+
static double LnRefV2(double& value)
257+
{
258+
//if (value <= 0) {}else//Error if equal or less than 0
259+
if (value == 1.0)
260+
return 0.0;
261+
if(value<1.0)
262+
{
263+
double W = (value - 1.0) / (value + 1.0);//(-0.5)/(1.5)=-1/3
264+
double TotalRes = W;
265+
W *= -1;
266+
double LastPow = W;
267+
double WSquared = W * W;
268+
double AddRes;
269+
int WPow = 3;
270+
do
271+
{
272+
LastPow *= WSquared;
273+
AddRes = LastPow / WPow;
274+
TotalRes -= AddRes;
275+
WPow += 2;
276+
} while (AddRes > 0.000000001);//Total Result should be -0.346573590279972654708616060729088284037750067180127627060340004746696810984847357802931663498209344
277+
return TotalRes * 2;//Should result in -0.693147180559
278+
}
279+
else if (value < 2.0)//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
280+
{
281+
double threshold = 0.000000005;
282+
double base = value - 1; // Base of the numerator; exponent will be explicit
283+
int den = 1; // Denominator of the nth term
284+
bool posSign = true; // Used to swap the sign of each term
285+
double term = base; // First term
286+
double prev; // Previous sum
287+
double result = term; // Kick it off
288+
289+
do
290+
{
291+
den++;
292+
posSign = !posSign;
293+
term *= base;
294+
prev = result;
295+
if (posSign)
296+
result += term / den;
297+
else
298+
result -= term / den;
299+
} while (abs(prev - result) > threshold);
300+
301+
return result;
302+
}
303+
else//Returns a positive value(http://www.netlib.org/cephes/qlibdoc.html#qlog)
304+
{//Increasing iterations brings closer to accurate result(Larger numbers need more iterations to get accurate level of result)
305+
//double W = (value - 1) / (value + 1);
306+
double TotalRes = (value - 1) / (value + 1);//W;
307+
double LastPow = TotalRes;
308+
double WSquared = TotalRes * TotalRes;
309+
double AddRes;
310+
int WPow = 3;
311+
do
312+
{
313+
LastPow *= WSquared;
314+
AddRes = LastPow / WPow;//double::PowRef(W, WPow) / WPow;
315+
TotalRes += AddRes; WPow += 2;
316+
} while (AddRes > 0.000000001);
317+
return TotalRes * 2;
318+
}
319+
}
320+
251321
/// <summary>
252322
/// Natural log (Equivalent to Log_E(value))
253323
/// </summary>

0 commit comments

Comments
 (0)