|
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 "Symbian Foundation License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32\euser\maths\um_mod.cpp |
|
15 // Writes the remainder of aSrc/aModulus to aTrg |
|
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 EXPORT_C TInt Math::Mod(TReal &aTrg,const TReal &aSrc,const TReal &aModulus) |
|
28 /** |
|
29 Calculates the modulo remainder. |
|
30 |
|
31 This is the value of p mod q, the modulo remainder when dividing p by q. |
|
32 The result is given by p - q int (p/q): |
|
33 it has the same sign as p: |
|
34 thus, 5 mod 3 = 2, -5 mod 3 = -2. |
|
35 No error is raised if non-integer arguments are passed. |
|
36 |
|
37 @param aTrg A reference containing the result. |
|
38 @param aSrc The p argument to the mod function. |
|
39 @param aModulus The q argument to the mod function. |
|
40 |
|
41 @return KErrNone if successful, otherwise another of |
|
42 the system-wide error codes. |
|
43 */ |
|
44 // |
|
45 // Floating point modulo arithmetic. |
|
46 // |
|
47 { |
|
48 |
|
49 TRealX f1,f2; |
|
50 TInt r=f1.Set(aSrc); |
|
51 if (r!=KErrNone) |
|
52 { |
|
53 SetNaN(aTrg); |
|
54 return KErrArgument; |
|
55 } |
|
56 r=f2.Set(aModulus); |
|
57 if (r==KErrArgument || f2.IsZero()) |
|
58 { |
|
59 SetNaN(aTrg); |
|
60 return KErrArgument; |
|
61 } |
|
62 if (r==KErrOverflow) |
|
63 { |
|
64 aTrg=aSrc; |
|
65 return KErrNone; |
|
66 } |
|
67 if ((TInt(f1.iExp)-TInt(f2.iExp))>KMantissaBits) |
|
68 { |
|
69 SetZero(aTrg); |
|
70 return KErrTotalLossOfPrecision; |
|
71 } |
|
72 f1.ModEq(f2); |
|
73 return f1.GetTReal(aTrg); |
|
74 } |
|
75 |
|
76 #else // __USE_VFP_MATH |
|
77 |
|
78 // definitions come from RVCT math library |
|
79 extern "C" TReal fmod(TReal,TReal); |
|
80 |
|
81 EXPORT_C TInt Math::Mod(TReal& aTrg, const TReal& aSrc, const TReal &aModulus) |
|
82 { |
|
83 SReal64 *pSrc=(SReal64 *)&aSrc; |
|
84 SReal64 *pModulus=(SReal64 *)&aModulus; |
|
85 |
|
86 if (pSrc->exp==0 || pModulus->exp==0 || pSrc->exp==KSpecialExponent || pModulus->exp==KSpecialExponent) |
|
87 { |
|
88 TRealX f1,f2; |
|
89 TInt r=f1.Set(aSrc); |
|
90 if (r!=KErrNone) |
|
91 { |
|
92 SetNaN(aTrg); |
|
93 return KErrArgument; |
|
94 } |
|
95 r=f2.Set(aModulus); |
|
96 if (r==KErrArgument || f2.IsZero()) |
|
97 { |
|
98 SetNaN(aTrg); |
|
99 return KErrArgument; |
|
100 } |
|
101 if (r==KErrOverflow) |
|
102 { |
|
103 aTrg=aSrc; |
|
104 return KErrNone; |
|
105 } |
|
106 if ((TInt(f1.iExp)-TInt(f2.iExp))>KMantissaBits) |
|
107 { |
|
108 SetZero(aTrg); |
|
109 return KErrTotalLossOfPrecision; |
|
110 } |
|
111 } |
|
112 else if ((pSrc->exp - pModulus->exp) > KMantissaBits) |
|
113 { |
|
114 SetZero(aTrg); |
|
115 return KErrTotalLossOfPrecision; |
|
116 } |
|
117 |
|
118 aTrg = fmod(aSrc,aModulus); |
|
119 return KErrNone; |
|
120 } |
|
121 |
|
122 #endif |