|
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_int.cpp |
|
15 // Writes the integer part aTrg to aSrc (aSrc is either TReal,TInt16 orTInt32) |
|
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 #ifndef __REALS_MACHINE_CODED__ |
|
28 EXPORT_C TInt Math::Int(TReal &aTrg,const TReal &aSrc) |
|
29 /** |
|
30 Calculates the integer part of a number. |
|
31 |
|
32 The integer part is that before a decimal point. |
|
33 Truncation is toward zero, so that |
|
34 int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1. |
|
35 |
|
36 |
|
37 @param aTrg A reference containing the result. |
|
38 @param aSrc The number whose integer part is required. |
|
39 |
|
40 @return KErrNone if successful, otherwise another of |
|
41 the system-wide error codes. |
|
42 */ |
|
43 { |
|
44 TRealX f; |
|
45 TInt ret=f.Set(aSrc); |
|
46 if (ret!=KErrNone) |
|
47 { |
|
48 aTrg=aSrc; |
|
49 return(ret); |
|
50 } |
|
51 TInt intbits=f.iExp-0x7FFE; // number of integer bits in mantissa |
|
52 if (intbits<=0) |
|
53 { |
|
54 SetZero(aTrg,f.iSign&1); // no integer part |
|
55 return(KErrNone); |
|
56 } |
|
57 if (intbits>=KMantissaBits) |
|
58 { |
|
59 aTrg=aSrc; // fractional part is outside range of significance |
|
60 return(KErrNone); |
|
61 } |
|
62 |
|
63 TUint64 mask = ~(UI64LIT(0)); |
|
64 mask <<= (64 - intbits); |
|
65 |
|
66 f.iMantHi &= static_cast<TUint32>(mask >> 32); |
|
67 f.iMantLo &= static_cast<TUint32>(mask); |
|
68 |
|
69 f.GetTReal(aTrg); |
|
70 return(KErrNone); |
|
71 } |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 EXPORT_C TInt Math::Int(TInt16 &aTrg,const TReal &aSrc) |
|
77 /** |
|
78 Calculates the integer part of a number. |
|
79 |
|
80 The integer part is that before a decimal point. |
|
81 Truncation is toward zero, so that |
|
82 int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1. |
|
83 |
|
84 This function is suitable when the result is known to be small enough |
|
85 for a 16-bit signed integer. |
|
86 |
|
87 @param aTrg A reference containing the result. |
|
88 @param aSrc The number whose integer part is required. |
|
89 |
|
90 @return KErrNone if successful, otherwise another of |
|
91 the system-wide error codes. |
|
92 */ |
|
93 // |
|
94 // If the integer part of aSrc is in the range -32768 to +32767 |
|
95 // inclusive, write the integer part to the TInt16 at aTrg |
|
96 // Negative numbers are rounded towards zero. |
|
97 // If an overflow or underflow occurs, aTrg is set to the max/min value |
|
98 // |
|
99 { |
|
100 TRealX f; |
|
101 TInt ret=f.Set(aSrc); |
|
102 |
|
103 if (ret==KErrArgument) |
|
104 { |
|
105 aTrg=0; |
|
106 return(ret); |
|
107 } |
|
108 |
|
109 TInt intbits=f.iExp-0x7FFE; // number of integer bits in mantissa |
|
110 |
|
111 if (intbits<=0) |
|
112 { |
|
113 aTrg=0; |
|
114 return(KErrNone); |
|
115 } |
|
116 |
|
117 if (intbits>16) |
|
118 { |
|
119 aTrg=(TInt16)((f.iSign&1) ? KMinTInt16 : KMaxTInt16); |
|
120 return((f.iSign&1) ? KErrUnderflow : KErrOverflow); |
|
121 } |
|
122 |
|
123 TUint val = f.iMantHi >> (32 - intbits); |
|
124 |
|
125 if ((f.iSign&1)==0 && val>(TUint)KMaxTInt16) |
|
126 { |
|
127 aTrg=TInt16(KMaxTInt16); |
|
128 return(KErrOverflow); |
|
129 } |
|
130 |
|
131 if ((f.iSign&1) && val>(TUint)(KMaxTInt16+1)) |
|
132 { |
|
133 aTrg=TInt16(KMinTInt16); |
|
134 return(KErrUnderflow); |
|
135 } |
|
136 |
|
137 aTrg = (f.iSign&1) ? (TInt16)(-(TInt)val) : (TInt16)val; |
|
138 |
|
139 return(KErrNone); |
|
140 } |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 EXPORT_C TInt Math::Int(TInt32 &aTrg,const TReal &aSrc) |
|
146 /** |
|
147 Calculates the integer part of a number. |
|
148 |
|
149 The integer part is that before a decimal point. |
|
150 Truncation is toward zero, so that |
|
151 int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1. |
|
152 |
|
153 This function is suitable when the result is known to be small enough |
|
154 for a 32-bit signed integer. |
|
155 |
|
156 @param aTrg A reference containing the result. |
|
157 @param aSrc The number whose integer part is required. |
|
158 |
|
159 @return KErrNone if successful, otherwise another of |
|
160 the system-wide error codes. |
|
161 */ |
|
162 // |
|
163 // If the integer part of the float is in the range -2147483648 to +2147483647 |
|
164 // inclusive, write the integer part to the TInt32 at aTrg |
|
165 // Negative numbers are rounded towards zero. |
|
166 // If an overflow or underflow occurs, aTrg is set to the max/min value |
|
167 // |
|
168 { |
|
169 TRealX f; |
|
170 TInt ret=f.Set(aSrc); |
|
171 |
|
172 if (ret==KErrArgument) |
|
173 { |
|
174 aTrg=0; |
|
175 return(ret); |
|
176 } |
|
177 |
|
178 TInt intbits=f.iExp-0x7FFE; // number of integer bits in mantissa |
|
179 |
|
180 if (intbits<=0) |
|
181 { |
|
182 aTrg=0; |
|
183 return(KErrNone); |
|
184 } |
|
185 |
|
186 if (intbits>32) |
|
187 { |
|
188 aTrg=((f.iSign&1) ? KMinTInt32 : KMaxTInt32); |
|
189 return((f.iSign&1) ? KErrUnderflow : KErrOverflow); |
|
190 } |
|
191 |
|
192 TUint val = f.iMantHi >> (32 - intbits); |
|
193 |
|
194 if ((f.iSign&1)==0 && val>(TUint)KMaxTInt32) |
|
195 { |
|
196 aTrg=KMaxTInt32; |
|
197 return(KErrOverflow); |
|
198 } |
|
199 |
|
200 if ((f.iSign&1) && val>((TUint)KMaxTInt32+1)) |
|
201 { |
|
202 aTrg=KMinTInt32; |
|
203 return(KErrUnderflow); |
|
204 } |
|
205 |
|
206 aTrg=(f.iSign&1) ? -(TInt32)val : val; |
|
207 |
|
208 return(KErrNone); |
|
209 } |
|
210 |
|
211 #endif //__REALS_MACHINE_CODED__ |
|
212 |
|
213 #else // __USE_VFP_MATH |
|
214 |
|
215 // definitions come from RVCT math library |
|
216 extern "C" TReal modf(TReal,TReal*); |
|
217 |
|
218 EXPORT_C TInt Math::Int(TReal& aTrg, const TReal& aSrc) |
|
219 { |
|
220 if (Math::IsNaN(aSrc)) |
|
221 { |
|
222 SetNaN(aTrg); |
|
223 return KErrArgument; |
|
224 } |
|
225 if (Math::IsInfinite(aSrc)) |
|
226 { |
|
227 aTrg=aSrc; |
|
228 return KErrOverflow; |
|
229 } |
|
230 |
|
231 modf(aSrc,&aTrg); |
|
232 return KErrNone; |
|
233 } |
|
234 |
|
235 EXPORT_C TInt Math::Int(TInt32& aTrg, const TReal& aSrc) |
|
236 { |
|
237 TReal aIntPart; |
|
238 TInt r = Math::Int(aIntPart,aSrc); |
|
239 if (r==KErrArgument) |
|
240 { |
|
241 aTrg = 0; |
|
242 return r; |
|
243 } |
|
244 if (aIntPart>KMaxTInt32) |
|
245 { |
|
246 aTrg = KMaxTInt32; |
|
247 return KErrOverflow; |
|
248 } |
|
249 if (aIntPart<KMinTInt32) |
|
250 { |
|
251 aTrg = KMinTInt32; |
|
252 return KErrUnderflow; |
|
253 } |
|
254 aTrg = aIntPart; |
|
255 return KErrNone; |
|
256 } |
|
257 |
|
258 EXPORT_C TInt Math::Int(TInt16& aTrg, const TReal& aSrc) |
|
259 { |
|
260 TReal aIntPart; |
|
261 TInt r = Math::Int(aIntPart,aSrc); |
|
262 if (r==KErrArgument) |
|
263 { |
|
264 aTrg = 0; |
|
265 return r; |
|
266 } |
|
267 if (aIntPart>KMaxTInt16) |
|
268 { |
|
269 aTrg = KMaxTInt16; |
|
270 return KErrOverflow; |
|
271 } |
|
272 if (aIntPart<KMinTInt16) |
|
273 { |
|
274 aTrg = KMinTInt16; |
|
275 return KErrUnderflow; |
|
276 } |
|
277 aTrg = aIntPart; |
|
278 return KErrNone; |
|
279 } |
|
280 |
|
281 #endif |