1. /* sdflognw.cpp by K.Tsuru */
  2. // function ID = 3406 since ver. 2.18
  3. /***********************************************************************
  4. SDouble class with binary splitting.
  5. It provides log(x) using Newton's method i.e. by solving the equation
  6. f(y) = x - exp(y) = 0 (y = log(x)).
  7. It does iteration
  8. y1 = y0 + delta
  9. where delta = x * exp(-y0) - 1.0
  10. Since ver.2.30 the fixed point mode is used. See RecSqrt(x).
  11. ***********************************************************************/
  12. #ifndef SN_H
  13. #include "sn.h"
  14. #endif
  15. static const char* const func = "LogNW";
  16. //static const SDouble ONE(1.0);
  17. SDouble LogNW(const SDouble& x) {
  18. // pretreatment
  19. SDouble X, add;
  20. // x = X*10^exp. log(x) = log(X)+exp*log(10), add = exp*log(10), 0< X < 1
  21. if( GetLogxCalcMethod(x, X, add) ) return X; // x= 1 or 10, X=0 or log(10)
  22. RealSize C;
  23. uint max_sz = X.MaxSize();
  24. int itrmax = howpow2( (DFIGURES*max_sz)/DOUBLE_FIG+1 ) + 6;
  25. int count = 0;
  26. uint ef = (DOUBLE_FIG*2u)/DFIGURES, fig = C.EffFigures();
  27. bool fullPrec = false; //calclation is done in full precision or not
  28. double xD = doubleD(X);
  29. SDouble y(log(xD)), delta;
  30. if(ef > fig) ef = fig;
  31. do {
  32. if((ef = C.SetEffFig(ef)) >= fig) fullPrec = true;
  33. delta = X * Exp(-y) - ONE; // considerably slower than above
  34. y += delta;
  35. ef *= 2;
  36. if(ef >= fig) ef = fig;
  37. C.SetEffFig(0);
  38. count++;
  39. } while( ( !delta.IsMLT(X) && (count < itrmax) ) || !fullPrec); // add "()" since version 2.192
  40. if(count >= itrmax) X.SetError(X.FATAL, func, 34010);
  41. y.iterationCount = count;
  42. y += add;
  43. return y;
  44. }

sdflognw.cpp : last modifiled at 2016/08/25 16:34:35(1,604 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).