|
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 |