os/kernelhwsrv/kernel/eka/euser/maths/um_tan.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_tan.cpp
    15 // Tangent.
    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 TanCoeffs[] =
    29 	{
    30 	0x2168C235,0xC90FDAA2,0x7FFF0000,	// polynomial approximation to tan((pi/2)*x)
    31 	0x2DF4707D,0xA55DE731,0x7FFF0000,	// for |x|<=0.25
    32 	0xA9A1A71A,0xA335E33B,0x7FFF0000,
    33 	0x0BB9E431,0xA2FFFCDD,0x7FFF0000,
    34 	0x3E523A39,0xA2FA3863,0x7FFF0000,
    35 	0x8A35C401,0xA2F9D38B,0x7FFF0000,
    36 	0x91269411,0xA2F16003,0x7FFF0000,
    37 	0xDA32CC78,0xA3A93B13,0x7FFF0000,
    38 	0x4FB88317,0x9A146197,0x7FFF0000,
    39 	0x0D787ECE,0xE131DEE5,0x7FFF0000
    40 	};
    41 
    42 LOCAL_D const TUint32 Onedata[] = {0x00000000,0x80000000,0x7FFF0000};		// 1.0
    43 LOCAL_D const TUint32 Halfdata[] = {0x00000000,0x80000000,0x7FFE0000};		// 0.5
    44 LOCAL_D const TUint32 PiBy2Invdata[] = {0x4E44152A,0xA2F9836E,0x7FFE0000};	// 2/pi
    45 
    46 
    47 
    48 
    49 EXPORT_C TInt Math::Tan(TReal& aTrg, const TReal& aSrc)
    50 /**
    51 Calculates the tangent of a number.
    52 
    53 @param aTrg A reference containing the result.
    54 @param aSrc The argument of the tan function in radians. 
    55 
    56 @return KErrNone if successful, otherwise another of
    57         the system-wide error codes. 
    58 */
    59 	{
    60 	// Calculate tan(aSrc) and write result to aTrg.
    61 	// Algorithm:
    62 	//		Let x=aSrc/(pi/2). Throw away integer part, but if integer part odd
    63 	//			then replace final result y with -1/y
    64 	//			( use identities tan(x+n*pi)=tan(x), tan(x+pi/2)=-1/tan(x) )
    65 	//		Replace x with fractional part after division.
    66 	//		If x>=0.5, replace x with 1-x and replace result y with 1/y
    67 	//			( use identity tan(pi/2-x)=1/tan(x) )
    68 	//		If x>=0.25, replace x with 0.5-x and replace result y with (1-y)/(1+y)
    69 	//			( use identity tan(pi/4-x)=(1-tan(x))/(1+tan(x)) )
    70 	//		Use polynomial approximation to calculate tan(pi*x/2) for |x|<=0.25
    71 
    72 	const TRealX& One = *(const TRealX*)Onedata;
    73 	const TRealX& Half = *(const TRealX*)Halfdata;
    74 	const TRealX& PiBy2Inv = *(const TRealX*)PiBy2Invdata;
    75 
    76 	TRealX x;
    77 	TInt r=x.Set(aSrc);
    78 	if (r==KErrNone)
    79 		{
    80 		TInt8 sign=x.iSign;
    81 		x.iSign=0;
    82 		x*=PiBy2Inv;
    83 		TInt n=(TInt)x;
    84 		if (n<KMaxTInt && n>KMinTInt)
    85 			{
    86 			TInt flags=(n&1)<<1;
    87 			x-=TRealX(n);
    88 			if (x.iExp>=0x7FFE)
    89 				{
    90 				x=One-x;
    91 				flags^=2;
    92 				}
    93 			if (x.iExp>=0x7FFD)
    94 				{
    95 				x=Half-x;
    96 				flags^=1;
    97 				}
    98 			TRealX y;
    99 			PolyX(y,x*x,9,(const TRealX*)TanCoeffs);
   100 			y*=x;
   101 			if (flags==3)
   102 				y=(One+y)/(One-y);
   103 			else if (flags==2)
   104 				y=One/y;
   105 			else if (flags==1)
   106 				y=(One-y)/(One+y);
   107 			y.iSign=TInt8(sign ^ (n&1));
   108 			return y.GetTReal(aTrg);
   109 			}
   110 		}
   111 	SetNaN(aTrg);
   112 	return KErrArgument;
   113 	}
   114 
   115 #else // __USE_VFP_MATH
   116 
   117 // definitions come from RVCT math library
   118 extern "C" TReal tan(TReal);
   119 
   120 EXPORT_C TInt Math::Tan(TReal& aTrg, const TReal& aSrc)
   121 	{
   122 	if (aSrc<KMaxTInt && aSrc>KMinTInt)
   123 		{
   124 		aTrg = tan(aSrc);
   125 		if (Math::IsFinite(aTrg))
   126 			return KErrNone;
   127 		}
   128 	SetNaN(aTrg);
   129 	return KErrArgument;
   130 	}
   131 
   132 #endif