0
|
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_asin.cpp
|
|
15 |
// Arc sin.
|
|
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 |
#ifndef __USE_VFP_MATH
|
|
26 |
|
|
27 |
LOCAL_D const TUint32 ArcsinCoeffs[] =
|
|
28 |
{
|
|
29 |
0x00000000,0x80000000,0x7FFF0000, // polynomial approximation to arcsin(x)
|
|
30 |
0xAA893CD8,0xAAAAAAAA,0x7FFC0000, // for -0.5<=x<=0.5
|
|
31 |
0xD07ED410,0x99999999,0x7FFB0000,
|
|
32 |
0xB6C64A72,0xB6DB6D94,0x7FFA0000,
|
|
33 |
0xF5527DD4,0xF8E3995C,0x7FF90000,
|
|
34 |
0xA87499FB,0xB744B969,0x7FF90000,
|
|
35 |
0x2E8953AD,0x8E392B24,0x7FF90000,
|
|
36 |
0xFEDBB4E4,0xE3481C4A,0x7FF80000,
|
|
37 |
0x4A32ED70,0xC89998E1,0x7FF80000,
|
|
38 |
0x848A2B53,0xCCAE4AE5,0x7FF70000,
|
|
39 |
0x09C1F387,0xA587A043,0x7FF90000,
|
|
40 |
0x722B9041,0x8C9BD20B,0x7FF90001,
|
|
41 |
0xC88B75CC,0x850CE779,0x7FFA0000
|
|
42 |
};
|
|
43 |
|
|
44 |
LOCAL_D const TUint32 Onedata[] = {0x00000000,0x80000000,0x7FFF0000}; // 1.0
|
|
45 |
LOCAL_D const TUint32 Halfdata[] = {0x00000000,0x80000000,0x7FFE0000}; // 0.5
|
|
46 |
LOCAL_D const TUint32 Pidata[] = {0x2168C235,0xC90FDAA2,0x80000000}; // pi
|
|
47 |
LOCAL_D const TUint32 PiBy2data[] = {0x2168C235,0xC90FDAA2,0x7FFF0000}; // pi/2
|
|
48 |
|
|
49 |
LOCAL_C TInt CalcArcsinArccos(TReal& aTrg, TRealX& x, TBool aCos)
|
|
50 |
{
|
|
51 |
// Calculate arcsin (if aCos false) or arccos (if aCos true) of x
|
|
52 |
// and write result to aTrg.
|
|
53 |
// Algorithm (arcsin):
|
|
54 |
// If x>0.5, replace x with Sqrt((1-x)/2)
|
|
55 |
// ( use identity cos(x)=2(cos(x/2))^2-1 )
|
|
56 |
// Use polynomial approximation for arcsin(x), 0<=x<=0.5
|
|
57 |
// If original x>0.5, replace result y with pi/2-2y
|
|
58 |
|
|
59 |
const TRealX One = *(const TRealX*)Onedata;
|
|
60 |
const TRealX Half = *(const TRealX*)Halfdata;
|
|
61 |
const TRealX Pi = *(const TRealX*)Pidata;
|
|
62 |
const TRealX PiBy2 = *(const TRealX*)PiBy2data;
|
|
63 |
|
|
64 |
TInt sign=x.iSign&1;
|
|
65 |
x.iSign=0;
|
|
66 |
if (x<=One)
|
|
67 |
{
|
|
68 |
TBool big=(x>Half);
|
|
69 |
if (big)
|
|
70 |
{
|
|
71 |
x=One-x;
|
|
72 |
if (x.iExp>1)
|
|
73 |
x.iExp--;
|
|
74 |
TReal temp;
|
|
75 |
Math::Sqrt(temp, (TReal)x);
|
|
76 |
x=temp;
|
|
77 |
}
|
|
78 |
TRealX y;
|
|
79 |
Math::PolyX(y,x*x,12,(const TRealX*)ArcsinCoeffs);
|
|
80 |
y*=x;
|
|
81 |
if (big)
|
|
82 |
{
|
|
83 |
if (y.iExp)
|
|
84 |
y.iExp++;
|
|
85 |
if (aCos)
|
|
86 |
{
|
|
87 |
if (sign)
|
|
88 |
y=Pi-y;
|
|
89 |
}
|
|
90 |
else
|
|
91 |
{
|
|
92 |
y=PiBy2-y;
|
|
93 |
y.iSign=TInt8(sign);
|
|
94 |
}
|
|
95 |
}
|
|
96 |
else
|
|
97 |
{
|
|
98 |
y.iSign=TInt8(sign);
|
|
99 |
if (aCos)
|
|
100 |
y=PiBy2-y;
|
|
101 |
}
|
|
102 |
return y.GetTReal(aTrg);
|
|
103 |
}
|
|
104 |
return KErrArgument;
|
|
105 |
}
|
|
106 |
|
|
107 |
|
|
108 |
|
|
109 |
|
|
110 |
EXPORT_C TInt Math::ASin(TReal& aTrg, const TReal& aSrc)
|
|
111 |
/**
|
|
112 |
Calculates the principal value of the inverse sine of a number.
|
|
113 |
|
|
114 |
@param aTrg A reference containing the result in radians,
|
|
115 |
a value between -pi/2 and +pi/2.
|
|
116 |
@param aSrc The argument of the arcsin function, a value
|
|
117 |
between -1 and +1 inclusive.
|
|
118 |
|
|
119 |
@return KErrNone if successful, otherwise another of the system-wide
|
|
120 |
error codes.
|
|
121 |
*/
|
|
122 |
{
|
|
123 |
TRealX x;
|
|
124 |
TInt r=x.Set(aSrc);
|
|
125 |
if (r==KErrNone)
|
|
126 |
r=CalcArcsinArccos(aTrg,x,EFalse);
|
|
127 |
if (r==KErrNone)
|
|
128 |
return r;
|
|
129 |
SetNaN(aTrg);
|
|
130 |
return KErrArgument;
|
|
131 |
}
|
|
132 |
|
|
133 |
|
|
134 |
|
|
135 |
|
|
136 |
EXPORT_C TInt Math::ACos(TReal& aTrg, const TReal& aSrc)
|
|
137 |
/**
|
|
138 |
Calculates the principal value of the inverse cosine of a number.
|
|
139 |
|
|
140 |
@param aTrg A reference containing the result in radians,
|
|
141 |
a value between 0 and pi.
|
|
142 |
@param aSrc The argument of the arccos function, a value
|
|
143 |
between -1 and +1 inclusive.
|
|
144 |
|
|
145 |
@return KErrNone if successful, otherwise another of the system-wide
|
|
146 |
error codes.
|
|
147 |
*/
|
|
148 |
{
|
|
149 |
TRealX x;
|
|
150 |
TInt r=x.Set(aSrc);
|
|
151 |
if (r==KErrNone)
|
|
152 |
r=CalcArcsinArccos(aTrg,x,ETrue);
|
|
153 |
if (r==KErrNone)
|
|
154 |
return r;
|
|
155 |
SetNaN(aTrg);
|
|
156 |
return KErrArgument;
|
|
157 |
}
|
|
158 |
|
|
159 |
#else // __USE_VFP_MATH
|
|
160 |
|
|
161 |
// definitions come from RVCT math library
|
|
162 |
extern "C" TReal asin(TReal);
|
|
163 |
extern "C" TReal acos(TReal);
|
|
164 |
|
|
165 |
EXPORT_C TInt Math::ASin(TReal& aTrg, const TReal& aSrc)
|
|
166 |
{
|
|
167 |
aTrg = asin(aSrc);
|
|
168 |
if (Math::IsFinite(aTrg))
|
|
169 |
return KErrNone;
|
|
170 |
SetNaN(aTrg);
|
|
171 |
return KErrArgument;
|
|
172 |
}
|
|
173 |
|
|
174 |
EXPORT_C TInt Math::ACos(TReal& aTrg, const TReal& aSrc)
|
|
175 |
{
|
|
176 |
aTrg = acos(aSrc);
|
|
177 |
if (Math::IsFinite(aTrg))
|
|
178 |
return KErrNone;
|
|
179 |
SetNaN(aTrg);
|
|
180 |
return KErrArgument;
|
|
181 |
}
|
|
182 |
|
|
183 |
#endif
|