Closed sisirajaya closed 4 years ago
It is definitely in the number representation. I checked with other functions such as bcd::sin values do not match with std::sin values. Loos like exponent and mantissa computation for decimals are incorrect with exception of .1 is correct. I am not yet up-to-speed with evaluation is them to fix it.
t = .3 + E+0 03000000 00000000 00000000 00000000 00000000 tt = .03 + E-1 30000000 00000000 00000000 00000000 00000000 bcd sin(0.03) is 0.2955202067 double ::sin(0.03) is 0.0299955002
t = 3 * .1; t.DebugPrint("t = .3"); tt = t / 10.; tt.DebugPrint("tt = .03"); bexp = sin(tt); printf("bcd sin(0.03) is \t%20.10g\n", bexp.AsDouble()); printf("double ::sin(0.03) is \t%20.10g\n", ::sin(.03));
It Looks like tt = t/10 is the culprit... when the same number is assigned as a constant 0.02 the answers are correct.
tt= .2/10 --> + E-1 20000000 00000000 00000000 00000000 00000000 (BAD) tt= 0.02 --> + E-1 02000000 00000000 00000000 00000000 00000000 (GOOD)
t = 2 * .1; t.DebugPrint("t = .2"); --> t = .2 + E+0 02000000 00000000 00000000 00000000 00000000 tt = t / 10.; tt.DebugPrint("tt = .02"); --> tt = .02 + E-1 20000000 00000000 00000000 00000000 00000000 tt = 0.02; td = tt.AsDouble(); tt.DebugPrint("tt = .02"); --> tt = .02 + E-1 02000000 00000000 00000000 00000000 00000000 bexp = exp(tt); printf("bcd exp(0.02) is \t%20.10g\n", bexp.AsDouble()); --> 1.020214028 printf("double ::exp(0.02) is \t%20.10g\n", ::exp(.02)); ---> 1.02020134
Possible fix.
In function bcd::SetValueDouble m_exponent was changed to:
// Take care of exponent m_exponent = (short) ::floor(::log10(between));
taking floor of the log gives correct answers to all range of values.
In my experiment I narrowed down to the exponential bcd::Exp function giving wrong answers. bcd exp(0.01) is 1.010050167 Match double ::exp(0.01) is 1.010050167
bcd exp(0.02) is 1.221402758 Do not match with ::exp double ::exp(0.02) is 1.02020134 bcd exp(0.03) is 1.349858808 Do not match with ::exp double ::exp(0.03) is 1.030454534 I think the problem is the bcd representation of .01, .02 and .03.
t = .1 + E-1 10000000 00000000 00000000 00000000 00000000 tt = .01 + E-2 10000000 00000000 00000000 00000000 00000000
t = .2 + E+0 02000000 00000000 00000000 00000000 00000000 tt = .02 + E-1 20000000 00000000 00000000 00000000 00000000
t = .3 + E+0 03000000 00000000 00000000 00000000 00000000 tt = .03 + E-1 30000000 00000000 00000000 00000000 00000000
Here is the code fragment for your convenience:
bcd t = 1 * .1; t.DebugPrint("t = .1"); bcd tt = t / 10.; tt.DebugPrint("tt = .01"); bcd bexp = exp(tt); printf("bcd exp(0.01) is \t%20.10g\n", bexp.AsDouble()); printf("double ::exp(0.01) is \t%20.10g\n", ::exp(.01));
t = 2 * .1; t.DebugPrint("t = .2"); tt = t / 10.; tt.DebugPrint("tt = .02"); bexp = exp(tt); printf("bcd exp(0.02) is \t%20.10g\n", bexp.AsDouble()); printf("double ::exp(0.02) is \t%20.10g\n", ::exp(.02));
t = 3 * .1; t.DebugPrint("t = .3"); tt = t / 10.; tt.DebugPrint("tt = .03"); bexp = exp(tt); printf("bcd exp(0.03) is \t%20.10g\n", bexp.AsDouble()); printf("double ::exp(0.03) is \t%20.10g\n", ::exp(.03));