Logo Search packages:      
Sourcecode: abakus version File versions  Download package

HNumber HMath::ln ( const HNumber x ) [static]

Returns the natural logarithm of x. If x is non positive, returns NaN.

Definition at line 938 of file hmath.cpp.

References div(), HNumber::isNan(), HNumber::isPositive(), HNumber::isZero(), HNumber::nan(), and sqrt().

Referenced by acosh(), asinh(), atanh(), log(), and raise().

{
  if( x.isNan() )
    return HNumber::nan();
    
  if( !x.isPositive() )
    return HNumber::nan();
    
  // short circuit
  if( x == HNumber(10) )
    return HNumber("2.30258509299404568401799145468436420760110148862877"
                     "29760333279009675726102948650438303813865953227795"
                     "49054520440916779445247118780973037711833599749301"
                     "72118016928228381938415404059160910960135436620869" );
    
  // useful constants
  HNumber two(2);
  HNumber one(1);
  HNumber half("0.5");

  // adjust so that x is between 0.5 and 2.0
  // use the fact that ln(x^2) = 2*ln(x)
  HNumber xs( x );
  unsigned factor = 2;
  while( xs >= two )
  {
    factor *= 2;
    xs = HMath::sqrt( xs );
  }
  while( xs <= half )
  {
    factor *= 2;
    xs = HMath::sqrt( xs );
  }
  
  // Taylor expansion: ln(x) = 2(a+a^3/3+a^5/5+...) 
  // where a=(x-1)/(x+1)
  HNumber p = xs - 1;
  HNumber q = xs + 1;
  HNumber a = p / q;
  HNumber as = a*a;
  HNumber t = a;
  HNumber sum = a;
  
  // loop for the series (limited to avoid nasty cases)
  for( int i = 3; i < HMATH_MAX_PREC; i+= 2 )
  {
    t *= as;
    if( t.isZero() ) break;
    HNumber s = HMath::div( t, HNumber(i) );
    if( s.isZero() ) break;
    sum += s;
  }
  
  HNumber result = sum * HNumber( factor );
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index