--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/maths/um_sin.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,190 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\euser\maths\um_sin.cpp
+// Floating point sine and cosine functions
+//
+//
+
+#include "um_std.h"
+
+#if defined(__USE_VFP_MATH) && !defined(__CPU_HAS_VFP)
+#error __USE_VFP_MATH was defined but not __CPU_HAS_VFP - impossible combination, check variant.mmh
+#endif
+
+
+#ifndef __USE_VFP_MATH
+
+LOCAL_D const TUint32 SinCoeffs[] =
+ {
+ 0x2168C235,0xC90FDAA2,0x80000000, // polynomial approximation to sin(pi*x)
+ 0x2DF200BF,0xA55DE731,0x80010001, // for |x| <= 0.25
+ 0xAC273AA1,0xA335E33B,0x80000000,
+ 0x5AB23F44,0x99696671,0x7FFE0001,
+ 0xD585EAFE,0xA83C17D9,0x7FFB0000,
+ 0xA30DE7AD,0xF1802BAC,0x7FF70001,
+ 0xF57FD821,0xF1F6A1C9,0x7FF30000
+ };
+
+LOCAL_D const TUint32 CosCoeffs[] =
+ {
+ 0x00000000,0x80000000,0x7FFF0000, // polynomial approximation to cos(pi*x)
+ 0xF22EF286,0x9DE9E64D,0x80010001, // for |x| <= 0.25
+ 0xDAD59F90,0x81E0F840,0x80010000,
+ 0xE4E45144,0xAAE9E3F1,0x7FFF0001,
+ 0x3232D733,0xF0FA8342,0x7FFC0000,
+ 0x03E16BB8,0xD368F6A3,0x7FF90001,
+ 0x712FD084,0xFCE66DE2,0x7FF50000,
+ 0x9E5353EE,0xD94951B0,0x7FF10001
+ };
+
+LOCAL_D const TUint32 PiInvdata[] = {0x4E44152A,0xA2F9836E,0x7FFD0000}; // 1/pi
+LOCAL_D const TUint32 Halfdata[] = {0x00000000,0x80000000,0x7FFE0000}; // 0.5
+LOCAL_D const TUint32 Onedata[] = {0x00000000,0x80000000,0x7FFF0000}; // 1.0
+
+LOCAL_C TInt CalcSinCos(TReal& aTrg, TRealX& aSrc, TBool aCos)
+ {
+ // Calculate sin(aSrc) if aCos=false or cos(aSrc) if aCos=true
+ // and write result to aTrg.
+ // Algorithm:
+ // Divide aSrc by pi and throw away integer part, but change sign
+ // of result if integer part odd. Replace aSrc with remainder.
+ // ( use identities sin(x+n*pi)=(-1)^n*sin(x)
+ // cos(x+n*pi)=(-1)^n*cos(x) )
+ // If aSrc>=0.5 replace aSrc with 1-aSrc, and change sign of result
+ // if cos required.
+ // ( use identities sin(pi-x)=sin(x), cos(pi-x)=-cos(x) )
+ // If aSrc>=0.25 replace aSrc with 0.5-aSrc and swap sin and cos
+ // ( use identities sin(pi/2-x)=cos(x), cos(pi/2-x)=sin(x) )
+ // Use polynomial approximation to evaluate sin(pi*x) or cos(pi*x)
+ // for |x|<=0.25
+
+ const TRealX& One = *(const TRealX*)Onedata;
+ const TRealX& Half = *(const TRealX*)Halfdata;
+ const TRealX& PiInv = *(const TRealX*)PiInvdata;
+
+ TRealX y;
+ aSrc*=PiInv;
+ TInt n=(TInt)aSrc;
+ if (n<KMaxTInt && n>KMinTInt)
+ {
+ aSrc-=TRealX(n);
+ TInt sign=0;
+ if (!aCos)
+ sign=aSrc.iSign & 1;
+ sign^=n;
+ aSrc.iSign=0;
+ if (aSrc.iExp>=0x7FFE) // if remainder>=pi/2
+ {
+ aSrc=One-aSrc;
+ if (aCos)
+ sign^=1;
+ }
+ if (aSrc.iExp>=0x7FFD) // if remainder>=pi/4
+ {
+ aSrc=Half-aSrc; // take complementary angle
+ aCos=!aCos; // and swap sin and cos
+ }
+ if (aCos)
+ Math::PolyX(y,aSrc*aSrc,7,(const TRealX*)CosCoeffs);
+ else
+ {
+ Math::PolyX(y,aSrc*aSrc,6,(const TRealX*)SinCoeffs);
+ y*=aSrc;
+ }
+ if (sign & 1)
+ y=-y;
+ return y.GetTReal(aTrg);
+ }
+ return KErrArgument;
+ }
+
+
+
+
+EXPORT_C TInt Math::Sin(TReal& aTrg, const TReal& aSrc)
+/**
+Calculates the sine of a number.
+
+@param aTrg A reference containing the result.
+@param aSrc The argument of the sin function in radians.
+
+@return KErrNone if successful, otherwise another of
+ the system-wide error codes.
+*/
+ {
+ TRealX x;
+ TInt r=x.Set(aSrc);
+ if (r==KErrNone)
+ r=CalcSinCos(aTrg,x,EFalse);
+ if (r==KErrNone)
+ return r;
+ SetNaN(aTrg);
+ return KErrArgument;
+ }
+
+
+
+
+EXPORT_C TInt Math::Cos(TReal& aTrg, const TReal& aSrc)
+/**
+Calculates the cosine of a number.
+
+@param aTrg A reference containing the result.
+@param aSrc The argument of the cos function in radians
+
+@return KErrNone if successful, otherwise another of
+ the system-wide error codes.
+*/
+ {
+ TRealX x;
+ TInt r=x.Set(aSrc);
+ if (r==KErrNone)
+ r=CalcSinCos(aTrg,x,ETrue);
+ if (r==KErrNone)
+ return r;
+ SetNaN(aTrg);
+ return KErrArgument;
+ }
+
+#else // __USE_VFP_MATH
+
+// definitions come from RVCT math library
+extern "C" TReal sin(TReal);
+extern "C" TReal cos(TReal);
+
+EXPORT_C TInt Math::Sin(TReal& aTrg, const TReal& aSrc)
+ {
+ if (aSrc<KMaxTInt && aSrc>KMinTInt)
+ {
+ aTrg = sin(aSrc);
+ if (Math::IsFinite(aTrg))
+ return KErrNone;
+ }
+ SetNaN(aTrg);
+ return KErrArgument;
+ }
+
+EXPORT_C TInt Math::Cos(TReal& aTrg, const TReal& aSrc)
+ {
+ if (aSrc<KMaxTInt && aSrc>KMinTInt)
+ {
+ aTrg = cos(aSrc);
+ if (Math::IsFinite(aTrg))
+ return KErrNone;
+ }
+ SetNaN(aTrg);
+ return KErrArgument;
+ }
+
+#endif