os/kernelhwsrv/kernel/eka/euser/maths/um_ln.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\euser\maths\um_ln.cpp
    15 // Natural log.
    16 // 
    17 //
    18 
    19 #include "um_std.h"
    20 
    21 #if defined(__USE_VFP_MATH) && !defined(__CPU_HAS_VFP)
    22 #error	__USE_VFP_MATH was defined but not __CPU_HAS_VFP - impossible combination, check variant.mmh 
    23 #endif
    24 
    25 
    26 #ifndef __USE_VFP_MATH
    27 
    28 LOCAL_D const TUint32 ArtanhCoeffs[] =
    29 	{
    30 	0x5C17F0BC,0xB8AA3B29,0x80010000,	// polynomial approximation to (4/ln2)artanh(x)
    31 	0xD02489EE,0xF6384EE1,0x7FFF0000,	// for |x| <= (sqr2-1)/(sqr2+1)
    32 	0x7008CA5F,0x93BB6287,0x7FFF0000,
    33 	0xE32D1D6B,0xD30BB16D,0x7FFE0000,
    34 	0x461D071E,0xA4257CE2,0x7FFE0000,
    35 	0xC3B0EC87,0x8650D459,0x7FFE0000,
    36 	0x53BEC0CD,0xE23137E3,0x7FFD0000,
    37 	0xC523F21B,0xDAF79221,0x7FFD0000
    38 	};
    39 
    40 LOCAL_D const TUint32 Ln2By2data[] = {0xD1CF79AC,0xB17217F7,0x7FFD0000};	// (ln2)/2
    41 LOCAL_D const TUint32 Sqr2data[] = {0xF9DE6484,0xB504F333,0x7FFF0000};		// sqr2
    42 LOCAL_D const TUint32 Sqr2Invdata[] = {0xF9DE6484,0xB504F333,0x7FFE0000};	// 1/sqr2
    43 LOCAL_D const TUint32 Onedata[] = {0x00000000,0x80000000,0x7FFF0000};		// 1.0
    44 
    45 
    46 
    47 
    48 EXPORT_C TInt Math::Ln(TReal& aTrg, const TReal& aSrc)
    49 /**
    50 Calculates the natural logarithm of a number.
    51 
    52 @param aTrg A reference containing the result. 
    53 @param aSrc The number whose natural logarithm is required.
    54 
    55 @return KErrNone if successful, otherwise another of
    56         the system-wide error codes. 
    57 */
    58 	{
    59 	// Calculate ln(aSrc) and write to aTrg
    60 	// Algorithm:
    61 	//		Calculate log2(aSrc) and multiply by ln2
    62 	//		log2(aSrc)=log2(2^e.m) e=exponent of aSrc, m=mantissa 1<=m<2
    63 	//		log2(aSrc)=e+log2(m)
    64 	//		If e=-1 (0.5<=aSrc<1), let x=aSrc else let x=mantissa(aSrc)
    65 	//		If x>Sqr2, replace x with x/Sqr2
    66 	//		If x<Sqr2/2, replace x with x*Sqr2
    67 	//		Replace x with (x-1)/(x+1)
    68 	//		Use polynomial to calculate artanh(x) for |x| <= (sqr2-1)/(sqr2+1)
    69 	//			( use identity ln(x) = 2artanh((x-1)/(x+1)) )
    70 
    71 	TRealX x;
    72 	const TRealX& Ln2By2=*(const TRealX*)Ln2By2data;
    73 	const TRealX& Sqr2=*(const TRealX*)Sqr2data;
    74 	const TRealX& Sqr2Inv=*(const TRealX*)Sqr2Invdata;
    75 	const TRealX& One=*(const TRealX*)Onedata;
    76 
    77 	TInt r=x.Set(aSrc);
    78 	if (r==KErrNone)
    79 		{
    80 		if (x.iExp==0)
    81 			{
    82 			SetInfinite(aTrg,1);
    83 			return KErrOverflow;
    84 			}
    85 		if (x.iSign&1)
    86 			{
    87 			SetNaN(aTrg);
    88 			return KErrArgument;
    89 			}
    90 		TInt n=(x.iExp-0x7FFF)<<1;
    91 		x.iExp=0x7FFF;
    92 		if (n!=-2)
    93 			{
    94 			if (x>Sqr2)
    95 				{
    96 				x*=Sqr2Inv;
    97 				n++;
    98 				}
    99 			}
   100 		else 
   101 			{
   102 			n=0;
   103 			x.iExp=0x7FFE;
   104 			if (x<Sqr2Inv)
   105 				{
   106 				x*=Sqr2;
   107 				n--;
   108 				}
   109 			}
   110 		x=(x-One)/(x+One);	// ln(x)=2artanh((x-1)/(x+1))
   111 		TRealX y;
   112 		PolyX(y,x*x,7,(const TRealX*)ArtanhCoeffs);
   113 		y*=x;
   114 		y+=TRealX(n);
   115 		y*=Ln2By2;
   116 		return y.GetTReal(aTrg);
   117 		}
   118 	if (r==KErrArgument || (r==KErrOverflow && (x.iSign&1)))
   119 		{
   120 		SetNaN(aTrg);
   121 		return KErrArgument;
   122 		}
   123 	SetInfinite(aTrg,0);
   124 	return KErrOverflow;
   125 	}
   126 
   127 #else // __USE_VFP_MATH
   128 
   129 // definitions come from RVCT math library
   130 extern "C" TReal log(TReal);
   131 
   132 EXPORT_C TInt Math::Ln(TReal& aTrg, const TReal& aSrc)
   133 	{
   134 	aTrg = log(aSrc);
   135 	if (Math::IsFinite(aTrg))
   136 		return KErrNone;
   137 	if (Math::IsInfinite(aTrg))
   138 		return KErrOverflow;
   139 	SetNaN(aTrg);
   140 	return KErrArgument;
   141 	}
   142 
   143 #endif