|
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_rtod.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include "um_std.h" |
|
19 |
|
20 #include <e32debug.h> |
|
21 |
|
22 #define KNeedsRounding 0x1000 |
|
23 #if (KRealFormatTypeFlagsMask| KRealFormatTypesMask) & KNeedsRounding |
|
24 #error KNeedsRounding already uses 0x1000 |
|
25 #endif |
|
26 |
|
27 const TInt KMinThreeDigitExponent=100; |
|
28 |
|
29 _LIT8(KLit8Plus,"+"); |
|
30 _LIT8(KLit8Minus,"-"); |
|
31 _LIT8(KLit8Zero,"0"); |
|
32 _LIT8(KLit8Inf,"Inf"); |
|
33 _LIT8(KLit8Nan,"NaN"); |
|
34 |
|
35 LOCAL_C TInt round(const TText8* aBuf, const TInt aLen, TBool aExact) |
|
36 // |
|
37 // Round number in buffer depending on digit at aBuf[aLen]. |
|
38 // Return value is carry from most significant digit. |
|
39 // |
|
40 { |
|
41 __ASSERT_DEBUG(aLen>=0,Panic(EMathUnexpectedError1)); |
|
42 TText8* pB=(TText8*)aBuf+aLen; |
|
43 if (*pB<'5') |
|
44 return 0; // round down |
|
45 if (*pB=='5' && aExact && aLen>0 && !(pB[-1]&1)) |
|
46 return 0; // exactly half way - round to even |
|
47 while(--pB>=aBuf) |
|
48 { |
|
49 TText8 d=*pB; |
|
50 if (d<'9') |
|
51 { |
|
52 ++d; |
|
53 *pB=d; |
|
54 return 0; |
|
55 } |
|
56 *pB='0'; |
|
57 } |
|
58 // carry propagates to exponent |
|
59 *++pB='1'; |
|
60 if (aLen>0) |
|
61 pB[aLen]='0'; |
|
62 return 1; |
|
63 } |
|
64 |
|
65 TUint mult10(TUint64& a) |
|
66 // |
|
67 // Multiply a 64-bit binary fraction in a (MSB=2^-1) by 10 |
|
68 // Return the fractional part in a, the integer part in the return value. |
|
69 // |
|
70 { |
|
71 const TUint64 ten = 10; |
|
72 TUint64 high; |
|
73 Math::UMul64(a, ten, high, a); |
|
74 return static_cast<TUint>(high); |
|
75 } |
|
76 |
|
77 LOCAL_C TInt fDigLim(TDes8& aTrg, const TReal& aSrc, TInt& aExp, TInt aPrec) |
|
78 // |
|
79 // Convert the TReal at address aSrc to a decimal form suitable for use by a |
|
80 // formatting routine. Writes the result into the descriptor at aTrg and the |
|
81 // exponent in aExp. Returns the length of the string or a negative error number. |
|
82 // |
|
83 // AnnW, November 1996 - changed to handle all numbers in TReal64/96 range. |
|
84 // |
|
85 // The first character in aBuf is one of: |
|
86 // |
|
87 // '0' - indicates that aSrc is exactly zero. |
|
88 // |
|
89 // '+' - indicates a positive number and is followed by between 1 and KMaxPrecision |
|
90 // decimal digits representing a mantissa in the range 0.1 to less than 1.0 which |
|
91 // corresponds to the decimal exponent returned in aExp. |
|
92 // |
|
93 // '-' - indicates a negative mantissa and is otherwise the same as for '+'. |
|
94 // |
|
95 { |
|
96 |
|
97 TRealX x; |
|
98 TInt r=x.Set(aSrc); |
|
99 |
|
100 if (x.IsZero()) |
|
101 { |
|
102 aTrg=KLit8Zero(); |
|
103 return 1; |
|
104 } |
|
105 else // sets sign in all cases, including specials |
|
106 aTrg=(x.iSign ? KLit8Minus() : KLit8Plus()); |
|
107 |
|
108 if (r!=KErrNone) |
|
109 return r; |
|
110 |
|
111 x.iSign=0; |
|
112 TInt e=TInt(x.iExp)-0x7fff; // 2^e<=Abs(x)<2^(e+1) |
|
113 e*=19728; // log10(2)*65536 = 19728.301796... |
|
114 // max error due to omission of fractional part is 9889 (towards zero) |
|
115 e-=9889; // account for error, e may be too small by up to 19778 |
|
116 // Now have 10^(e/65536)<=Abs(x)<4.007*10^(e/65536) |
|
117 e>>=16; // Divide by 65536 - this always rounds towards -infinity |
|
118 // Now have 10^e<=Abs(x)<40.07*10^e |
|
119 e+=1; // Now have 0.1<=Abs(x)/10^e<4.07 |
|
120 Math::MultPow10X(x,-e); // x*=10^-e so now 0.1<=x<4.07 (rel error <= 8 units of 0.5LSB) |
|
121 if (x.iExp>=0x7fff) |
|
122 { |
|
123 ++e; |
|
124 Math::MultPow10X(x,-1); // if x>=1, multiply x by 10^-1 and increment e |
|
125 } |
|
126 // relative error now <= 11 units of 0.5LSB |
|
127 |
|
128 TUint64 mantissa = MAKE_TUINT64(x.iMantHi, x.iMantLo); |
|
129 |
|
130 if (x.iExp<0x7ffe) |
|
131 mantissa >>= (0x7ffe - x.iExp); // shift to make exponent 0x7ffe, i.e. mantissa in range 0.1<=m<1 |
|
132 |
|
133 TInt prec = aPrec; |
|
134 if (prec > KIEEEDoubleInjectivePrecision) |
|
135 prec = KIEEEDoubleInjectivePrecision; |
|
136 |
|
137 while ( mantissa && (aTrg.Length() < (prec + 2)) ) |
|
138 { |
|
139 TUint d = mult10(mantissa); |
|
140 aTrg.Append(d+'0'); |
|
141 } |
|
142 if (aTrg.Length()>=prec+2) |
|
143 { |
|
144 e+=round(aTrg.Ptr()+1,prec,mantissa==0); |
|
145 aTrg.SetLength(prec+1); |
|
146 } |
|
147 aExp=e; |
|
148 return aTrg.Length(); |
|
149 } |
|
150 |
|
151 LOCAL_C TInt doExponent(TDes8* This, TDes8& aDigBuf, const TInt afDigLimSize, TInt aExp, |
|
152 const TInt aNumPlcs, const TInt aNumSpace, const TText aPoint, const TUint flags) |
|
153 // |
|
154 // Convert the intermediate number represented in aDigBuf into its exponential representation |
|
155 // and place into aTrg. |
|
156 // This representation ensures that numbers are displayed to aNumDecPlcs+1 significant figures, |
|
157 // but this is NOT a constant value in KTRealFormatGeneral mode. |
|
158 // |
|
159 // AnnW, November 1996 - changed to be able to take three-figure exponents if allowed by flags. |
|
160 // |
|
161 { |
|
162 |
|
163 TInt err; |
|
164 TInt expSpace; |
|
165 TInt useSigFigs=flags & KUseSigFigs; |
|
166 TInt nDig=(useSigFigs ? Min(aNumPlcs,afDigLimSize) : aNumPlcs+1); |
|
167 TInt threeDigitExp=flags & KAllowThreeDigitExp; |
|
168 |
|
169 if ((flags & KNeedsRounding) && afDigLimSize>nDig) |
|
170 aExp+=round(aDigBuf.Ptr()+1,nDig,EFalse); |
|
171 |
|
172 if (useSigFigs) // discard trailing zeros |
|
173 { |
|
174 while(nDig>1 && aDigBuf[nDig]=='0') |
|
175 { |
|
176 nDig--; |
|
177 } |
|
178 } |
|
179 |
|
180 if (aDigBuf[0]!='0') |
|
181 // 100.5 is stored in aDigBuf as +1005 with and exp of 3, but it is to be displayed |
|
182 // as 1.005 so exp must be decremented to 2 |
|
183 aExp--; |
|
184 |
|
185 // Added by AnnW |
|
186 if (threeDigitExp) |
|
187 { |
|
188 expSpace=(Abs(aExp)>=KMinThreeDigitExponent)?5:4; |
|
189 } |
|
190 else |
|
191 { |
|
192 err=(aExp<=-KMinThreeDigitExponent ? KErrUnderflow : (aExp>=KMinThreeDigitExponent ? KErrOverflow : KErrNone)); |
|
193 if (err!=KErrNone) |
|
194 return(err); |
|
195 expSpace=4; |
|
196 } |
|
197 |
|
198 // Check that number will fit in aNumSpace |
|
199 if (aNumSpace<(expSpace+nDig+(nDig>1?1:0))) |
|
200 // exponent + significant figures + point(if necessary) |
|
201 return(KErrGeneral); |
|
202 // end of added |
|
203 |
|
204 if (aDigBuf[0]=='0') // number to be converted is 0 |
|
205 { |
|
206 This->Append('0'); |
|
207 if (nDig>1 && !useSigFigs) |
|
208 { |
|
209 This->Append(aPoint); |
|
210 This->AppendFill('0',aNumPlcs); |
|
211 } |
|
212 } |
|
213 else |
|
214 { |
|
215 This->Append(TChar(aDigBuf[1])); |
|
216 if (nDig>1) |
|
217 { |
|
218 This->Append(aPoint); |
|
219 for (TInt ii=2; ii<=nDig; ii++) |
|
220 { |
|
221 if (!useSigFigs) |
|
222 // pad with zeros |
|
223 This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii]:'0')); |
|
224 else |
|
225 // do not pad with zeros |
|
226 This->Append(TChar(aDigBuf[ii])); |
|
227 } |
|
228 } |
|
229 } |
|
230 |
|
231 This->Append('E'); |
|
232 if (aExp<0) |
|
233 { |
|
234 aExp=-aExp; |
|
235 This->Append('-'); |
|
236 } |
|
237 else |
|
238 This->Append('+'); |
|
239 |
|
240 // Added by AnnW |
|
241 TInt tempExp; |
|
242 if (threeDigitExp && aExp>99) |
|
243 { |
|
244 This->Append(aExp/100+'0'); |
|
245 tempExp=aExp%100; |
|
246 } |
|
247 else |
|
248 tempExp = aExp; |
|
249 // end of added |
|
250 |
|
251 This->Append(tempExp/10+'0'); |
|
252 This->Append(tempExp%10+'0'); |
|
253 return(KErrNone); |
|
254 } |
|
255 |
|
256 LOCAL_C TInt doFixed(TDes8 *This,TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp,const TInt aNumDecPlcs, |
|
257 const TInt aNumSpace,const TRealFormat &aFormat,const TUint flags) |
|
258 // |
|
259 // Convert the intermediate number represented in aDigBuf into its fixed representation and |
|
260 // place into aTrg |
|
261 // |
|
262 // AnnW, November 1996 - changed to allow extra space to be left for potential sign, so that |
|
263 // positive and negative numbers of the same exponent are displayed to the same precision. |
|
264 // |
|
265 { |
|
266 |
|
267 TInt err; |
|
268 TInt doNotUseTriads=flags & KDoNotUseTriads; |
|
269 TInt newNumSpace=aNumSpace; |
|
270 // To allow positive and negative numbers with the same exponent to have the same number of |
|
271 // significant figures. |
|
272 if ((flags & KExtraSpaceForSign) && (aDigBuf[0]!='-')) |
|
273 newNumSpace--; |
|
274 |
|
275 TInt roundOffset = aNumDecPlcs+aExp; |
|
276 if (roundOffset>=0 && afDigLimSize>roundOffset && (flags & KNeedsRounding)) |
|
277 aExp+=round(aDigBuf.Ptr()+1,roundOffset,EFalse); |
|
278 |
|
279 if (newNumSpace<((aExp>0?aExp:1)+(aNumDecPlcs?aNumDecPlcs+1:0)+(!doNotUseTriads && aFormat.iTriLen && (aExp>(TInt)aFormat.iTriLen)?(aExp-1)/3:0))) |
|
280 // exponent +ve and space < space needed for (digits before point + point + decimal places + triads) |
|
281 { |
|
282 err=(aExp>0 ? KErrOverflow : KErrGeneral); |
|
283 return(err); |
|
284 } |
|
285 |
|
286 if (aExp<=0) // hence number is of the form 0.NNNN |
|
287 { |
|
288 This->Append('0'); |
|
289 if (aNumDecPlcs) |
|
290 { |
|
291 aExp=-aExp; |
|
292 TInt nDig=aNumDecPlcs-aExp; // number of digits required from aDigBuf |
|
293 This->Append(aFormat.iPoint); |
|
294 if (aExp>aNumDecPlcs) |
|
295 aExp=aNumDecPlcs; |
|
296 This->AppendFill('0',aExp); |
|
297 if (nDig>0) |
|
298 { |
|
299 for (TInt ii=1; ii<nDig+1; ii++) |
|
300 This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii]:'0')); |
|
301 } |
|
302 } |
|
303 else // no decimal places |
|
304 { |
|
305 if (aDigBuf[0]=='-') |
|
306 { |
|
307 This->Delete(0,2); // delete -0 from This |
|
308 This->Append('0'); |
|
309 } |
|
310 } |
|
311 } |
|
312 else // aExp > 0 hence number is of the form NNNN.NNNN |
|
313 { |
|
314 for (TInt jj=1,ii=aExp; ii; ii--,jj++) |
|
315 { |
|
316 if (!doNotUseTriads && aFormat.iTriLen && aExp>(TInt)aFormat.iTriLen && !(ii%3) && ii!=aExp) |
|
317 This->Append(aFormat.iTriad); |
|
318 This->Append(TChar(jj>=aDigBuf.Length() ? '0' : aDigBuf[jj])); |
|
319 } |
|
320 if (aNumDecPlcs>0) |
|
321 { |
|
322 This->Append(aFormat.iPoint); |
|
323 for (TInt ii=aExp+1; ii<aNumDecPlcs+aExp+1; ii++) |
|
324 This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii] : '0')); |
|
325 } |
|
326 } |
|
327 |
|
328 return(KErrNone); |
|
329 } |
|
330 |
|
331 LOCAL_C TInt doNoExponent(TDes8 *This, TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp, |
|
332 const TInt aMaxSigFigs,const TInt aNumSpace, const TRealFormat &aFormat,const TUint flags) |
|
333 // |
|
334 // Added by AnnW, November 1996 |
|
335 // Convert the intermediate number represented in aDigBuf into its no exponent representation |
|
336 // and place into aTrg |
|
337 // Changed April 1997 - If there is not enough space for the number of s.f., zeros, points, triads, |
|
338 // etc, then the number of significant figs is reduced to fit. Overflow if too big to fit and |
|
339 // underflow if no significance can be seen. |
|
340 // |
|
341 { |
|
342 |
|
343 TInt doNotUseTriads=flags & KDoNotUseTriads; |
|
344 TInt numSpace=aNumSpace; |
|
345 if ((flags & KExtraSpaceForSign) && (aDigBuf[0]!='-')) |
|
346 numSpace--; |
|
347 |
|
348 TInt nTriadSeps=(!doNotUseTriads && aFormat.iTriLen && (aExp>(TInt)aFormat.iTriLen))?(aExp-1)/3:0; |
|
349 TInt maxDig=Min(aMaxSigFigs,afDigLimSize); |
|
350 TInt maxSpace=numSpace-(aExp<=0?(2-aExp):((aExp<maxDig?1:aExp-maxDig)+nTriadSeps)); |
|
351 TInt nDig=Min(maxSpace,maxDig); |
|
352 if (afDigLimSize>nDig && nDig<15 && nDig>=0 && (flags & KNeedsRounding) && round(aDigBuf.Ptr()+1,nDig,EFalse)) |
|
353 aExp++; |
|
354 |
|
355 if (aDigBuf[0]=='0') // do zero first (numSpace>=0 so OK) |
|
356 This->Append('0'); |
|
357 else |
|
358 { |
|
359 // check for overflow/underflow |
|
360 if ((aExp+nTriadSeps)>numSpace) |
|
361 return(KErrOverflow); |
|
362 if (nDig<=0) |
|
363 return(KErrUnderflow); |
|
364 |
|
365 if ((flags&(TUint)KRealFormatTypesMask)!=(TUint)KRealFormatCalculator && aExp>aMaxSigFigs) |
|
366 return(KErrOverflow); |
|
367 |
|
368 TInt nDecPlcs=nDig-aExp; |
|
369 while(nDecPlcs>0 && aDigBuf[nDig]=='0') |
|
370 { // discard trailing zeros (already done in calculator) |
|
371 nDecPlcs--; |
|
372 nDig--; |
|
373 } |
|
374 |
|
375 if (aExp<=0) // hence number is of the form 0.NNNN |
|
376 { |
|
377 This->Append('0'); |
|
378 aExp=-aExp; |
|
379 // if (nDecPlcs<=0) do nothing |
|
380 if (nDecPlcs>0) |
|
381 { |
|
382 This->Append(aFormat.iPoint); |
|
383 This->AppendFill('0',aExp); |
|
384 for (TInt ii=1; ii<=nDig; ii++) |
|
385 This->Append(TChar(aDigBuf[ii])); |
|
386 } |
|
387 } |
|
388 else // aExp > 0 hence number is of the form NNNN.NNNN |
|
389 { |
|
390 for (TInt jj=1,ii=aExp; ii; ii--,jj++) |
|
391 { |
|
392 if (!doNotUseTriads && aFormat.iTriLen && aExp>(TInt)aFormat.iTriLen && !(ii%3) && ii!=aExp) |
|
393 This->Append(aFormat.iTriad); |
|
394 This->Append(TChar(jj<=nDig ? aDigBuf[jj] : '0')); |
|
395 } |
|
396 if (nDecPlcs>0) |
|
397 { |
|
398 This->Append(aFormat.iPoint); |
|
399 for (TInt ii=aExp+1; ii<=nDig; ii++) |
|
400 This->Append(TChar(aDigBuf[ii])); |
|
401 } |
|
402 } |
|
403 } |
|
404 |
|
405 return(KErrNone); |
|
406 } |
|
407 |
|
408 LOCAL_C TInt doGeneral(TDes8 *This,TReal aSrc,TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp, |
|
409 TInt aNumDecPlcs,const TInt aNumSpace,const TRealFormat &aFormat,TUint flags) __SOFTFP |
|
410 // |
|
411 // Convert the intermediate number represented in aDigBuf into either its fixed representation or |
|
412 // its exponential representation as appropriate and place the result in aTrg |
|
413 // |
|
414 // Annw, November 1996 - changed to allow space for sign in fixed mode, three-figure exponent. |
|
415 { |
|
416 |
|
417 TBool rounded=((flags & KNeedsRounding)==0); |
|
418 TInt nDig=aDigBuf.Length()-1; // no of digits without sign |
|
419 TInt type; |
|
420 |
|
421 // Set up tempNumSpace to allow for leaving one space free for +ve nos in fixed format |
|
422 TInt fixedNumSpace=aNumSpace; |
|
423 if ((flags & KExtraSpaceForSign) && (aDigBuf[0]!='-')) |
|
424 fixedNumSpace--; |
|
425 if (fixedNumSpace<=0) |
|
426 return(KErrGeneral); |
|
427 |
|
428 FOREVER |
|
429 { |
|
430 // If aNumSpace < 5 cannot use exponential format, i.e. not enough space for XE+NN. |
|
431 // If the exponent >= -3 (i.e. aExp >= -2), it is always more (or equally) efficient |
|
432 // to use non-exponential format for negative exponents, i.e. XE-03 takes same no of |
|
433 // spaces as 0.00X, and for positive exponents use fixed form as far as possible. |
|
434 |
|
435 // for Java do not used fixed format for exponents >=7 |
|
436 // expMax=Min(fixedNumSpace,7) |
|
437 // and replace "fixednumSpace" with "expMax" in next line |
|
438 |
|
439 if (aNumSpace<5 || (aExp>=-2 && aExp<=fixedNumSpace)) |
|
440 { |
|
441 type=KRealFormatFixed; |
|
442 |
|
443 // if there is at least one digit before decimal point or no. is zero |
|
444 if (aExp>0 || !aSrc) |
|
445 { |
|
446 if (nDig!=aExp) |
|
447 // nDig is the number of digits which will be used |
|
448 // a decimal point needed if exponent < digits in digbuf and numspace < nDig, |
|
449 // so nDig is one less than otherwise |
|
450 nDig=((nDig-aExp)>0 && fixedNumSpace>aExp)?Min(fixedNumSpace-1,nDig):Min(fixedNumSpace,nDig); |
|
451 aNumDecPlcs=nDig-aExp; |
|
452 } |
|
453 else |
|
454 { |
|
455 // need space for "0." and to avoid white spaces |
|
456 aNumDecPlcs=Min(fixedNumSpace-2,nDig-aExp); |
|
457 // need space for "0.0...0" before any digits used |
|
458 nDig=aNumDecPlcs+aExp; |
|
459 if (nDig<0) |
|
460 return KErrGeneral; |
|
461 } |
|
462 } |
|
463 else |
|
464 { |
|
465 type=KRealFormatExponent; // Do NOT use significant figures |
|
466 // Need to allow space for exponent |
|
467 TInt tempNumSpace=aNumSpace-4; // 4 = E+NN |
|
468 if ((flags & KAllowThreeDigitExp) && (Abs(aExp-1)>=100)) |
|
469 tempNumSpace--; // 5 = E+NNN |
|
470 // if more than one digit available and enough digits to fill space, need to reduce |
|
471 // number of digits to allow for '.' |
|
472 if (((nDig=Min(tempNumSpace,nDig))>1) && nDig==tempNumSpace) |
|
473 nDig--; |
|
474 // in any case, aNumDecPlcs is one less that the number of digits, |
|
475 // i.e. one digit before the point |
|
476 aNumDecPlcs=nDig-1; |
|
477 } |
|
478 // if too many digbuf chars to fit then we need to round |
|
479 // round() returns 1 if had to carry from msdigit |
|
480 if ((afDigLimSize>nDig && !rounded) && ((rounded=round(aDigBuf.Ptr()+1,nDig,EFalse))!=0)) |
|
481 aExp++; |
|
482 else |
|
483 break; |
|
484 } |
|
485 while(aNumDecPlcs>0 && aDigBuf[nDig]=='0') |
|
486 { // discard trailing zeros |
|
487 aNumDecPlcs--; |
|
488 nDig--; |
|
489 } |
|
490 flags=flags & ~KNeedsRounding; |
|
491 |
|
492 if (type==KRealFormatExponent) |
|
493 return(doExponent(This,aDigBuf,afDigLimSize,aExp,aNumDecPlcs,aNumSpace,(TText)aFormat.iPoint,flags)); |
|
494 return(doFixed(This,aDigBuf,afDigLimSize,aExp,aNumDecPlcs,aNumSpace,aFormat,flags)); |
|
495 } |
|
496 |
|
497 LOCAL_C TInt doCalculator(TDes8 *This,TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp, |
|
498 TInt aMaxSigFigs,const TInt aMaxSpace,const TRealFormat &aFormat, TUint flags) |
|
499 // |
|
500 // Added by AnnW, November 1996 |
|
501 // Convert the intermediate number represented in aDigBuf into either its no exponent or its |
|
502 // exponential representation with a fixed number of significant figures and place the result |
|
503 // in aTrg |
|
504 // |
|
505 { |
|
506 |
|
507 TBool threeDigExp=((flags & KAllowThreeDigitExp)!=0); |
|
508 |
|
509 // first check that enough space has been allowed for all the possible characters |
|
510 // point + sign + all sig figs + exponent |
|
511 if (aMaxSpace<(2+aMaxSigFigs+(threeDigExp?5:4))) |
|
512 return(KErrGeneral); |
|
513 |
|
514 // now discard trailing zeros |
|
515 TInt nDig=afDigLimSize; |
|
516 while(nDig>1 && aDigBuf[nDig]=='0') |
|
517 { |
|
518 nDig--; |
|
519 } |
|
520 |
|
521 TInt maxDig=Min(aMaxSigFigs,nDig); // max digs available |
|
522 TBool rounded=((flags & KNeedsRounding)==0); |
|
523 TInt type; |
|
524 TBool useNoExp; |
|
525 |
|
526 FOREVER |
|
527 { |
|
528 useNoExp=ETrue; |
|
529 nDig=maxDig; |
|
530 |
|
531 // use no exponent for all numbers which will not use > aMaxSigFigs digits |
|
532 if (aExp>aMaxSigFigs || (aExp<=0 && (1-aExp+nDig)>aMaxSigFigs)) |
|
533 useNoExp=EFalse; |
|
534 |
|
535 if (useNoExp) |
|
536 type=KRealFormatNoExponent; |
|
537 else |
|
538 { |
|
539 type=KRealFormatExponent; |
|
540 threeDigExp=((Abs(aExp-1)>=KMinThreeDigitExponent && threeDigExp)!=0); |
|
541 TInt temp=aMaxSpace-(threeDigExp?5:4); |
|
542 nDig=Min(maxDig,temp-((temp>1 && maxDig>1)?1:0)); |
|
543 } |
|
544 |
|
545 // if too many digbuf chars to fit then we need to round |
|
546 // round() returns 1 if had to carry from msdigit |
|
547 if ((afDigLimSize>nDig && !rounded) && ((rounded=round(aDigBuf.Ptr()+1,nDig,EFalse))!=0)) |
|
548 { |
|
549 aExp++; |
|
550 maxDig=1; |
|
551 } |
|
552 else |
|
553 break; |
|
554 } |
|
555 |
|
556 TInt numSpace=aMaxSpace-(aDigBuf[0]=='-'?1:0); |
|
557 flags=flags & ~KNeedsRounding; |
|
558 |
|
559 if (type==KRealFormatExponent) |
|
560 return(doExponent(This,aDigBuf,afDigLimSize,aExp,nDig,numSpace,(TText)aFormat.iPoint,flags)); |
|
561 else |
|
562 { |
|
563 flags|=KExtraSpaceForSign; |
|
564 return(doNoExponent(This,aDigBuf,afDigLimSize,aExp,nDig,numSpace,aFormat,flags)); |
|
565 } |
|
566 } |
|
567 |
|
568 TInt ProcessErrors(TDes8* aDes, TInt anError) |
|
569 { |
|
570 if (anError==KErrNone) |
|
571 return aDes->Length(); |
|
572 if (anError==KErrUnderflow) |
|
573 aDes->Append(TChar('0')); |
|
574 if (anError==KErrOverflow) |
|
575 aDes->Append(KLit8Inf()); |
|
576 if (anError==KErrArgument) |
|
577 aDes->Append(KLit8Nan()); |
|
578 return anError; |
|
579 } |
|
580 |
|
581 LOCAL_C TInt rtob(TDes8 *This,TReal aVal,const TRealFormat &aFormat) __SOFTFP |
|
582 // |
|
583 // Converts the real at aSrc. Returns the length of the converted string or an error number |
|
584 // if the buffer is too small, the number is out of range or there is insufficient KMaxPrecision |
|
585 // to represent the number. |
|
586 // |
|
587 // The conversion format is interpreted as follows: |
|
588 // KRealFormatFixed - ndec decimal places (including zero), negative values with a leading minus |
|
589 // sign, triad separators are available and a space may be left in front of positive numbers to |
|
590 // allow negative positve numbers to be given to the same precision. |
|
591 // KRealFormatExponent - exponent notation specifying either decimal places or significant |
|
592 // figures in the mantissa and a signed exponent given to a maximum of two or three digits, |
|
593 // and no triad separator. |
|
594 // KTRealFormatGeneral - converts either as fixed or exponent to make best use of the available |
|
595 // width. The number of decimal spaces is chosen automatically as a function of width |
|
596 // (ndec is ignored), no triad. |
|
597 // KRealFormatNoExponent - as KRealForamtFixed, but specifying maximum significant figures and |
|
598 // not introducing trailing zeros. |
|
599 // KRealFormatCalculator - as KRealFormatGeneral, but behaves as a conventional calculator. A |
|
600 // maximum number of significant figures is specified and the number is displayed without an |
|
601 // exponent whenever possible, with no trailing zeros and no triads. |
|
602 // |
|
603 // If an error value other than KErrGeneral is returned the real is converted to some string: |
|
604 // "+/-Inf" if the error is KErrOverflow, "NaN" if the error is KErrArgument or "0" if it is |
|
605 // KErrUnderflow. |
|
606 // |
|
607 { |
|
608 if (aFormat.iWidth>This->MaxLength()) |
|
609 return(KErrGeneral); |
|
610 TBuf8<0x20> digbuf; |
|
611 TInt exp=0; |
|
612 TInt numspace=aFormat.iWidth; |
|
613 TInt maxspace=numspace; |
|
614 TInt prec = KMaxPrecision; |
|
615 if (aFormat.iType & KRealInjectiveLimit) |
|
616 prec = KIEEEDoubleInjectivePrecision; |
|
617 else if (aFormat.iType & KGeneralLimit) |
|
618 prec = KPrecisionLimit; |
|
619 TInt ret=fDigLim(digbuf,aVal,exp,prec); |
|
620 digbuf.ZeroTerminate(); |
|
621 TInt type, flags; |
|
622 |
|
623 if (digbuf[0]=='0') |
|
624 exp=0; |
|
625 else |
|
626 { |
|
627 if (digbuf[0]=='-' && ret!=KErrArgument) // NaN has no sign |
|
628 { |
|
629 This->Append('-'); |
|
630 numspace--; |
|
631 } |
|
632 if (ret<0) |
|
633 return ProcessErrors(This, ret); |
|
634 else |
|
635 ret--; |
|
636 } |
|
637 |
|
638 //Added by AnnW |
|
639 if (numspace<=0) |
|
640 return(KErrGeneral); |
|
641 if (aFormat.iType & ~KRealFormatTypesMask & ~KRealFormatTypeFlagsMask) |
|
642 return(KErrGeneral); |
|
643 type=aFormat.iType & KRealFormatTypesMask; |
|
644 flags=((aFormat.iType & KRealFormatTypeFlagsMask)| KNeedsRounding); |
|
645 // end of added |
|
646 |
|
647 switch(type) |
|
648 { |
|
649 case KRealFormatFixed: |
|
650 flags=flags & ~KUseSigFigs; // if flag is NOT set and iTriLen!=0, uses triads |
|
651 ret=doFixed(This,digbuf,ret,exp,aFormat.iPlaces,numspace,aFormat,flags); |
|
652 break; |
|
653 case KRealFormatExponent: |
|
654 ret=doExponent(This,digbuf,ret,exp,aFormat.iPlaces,numspace,(TText)aFormat.iPoint,flags); |
|
655 break; |
|
656 case KRealFormatGeneral: |
|
657 flags=(flags & ~KUseSigFigs) | KDoNotUseTriads; |
|
658 ret=doGeneral(This,aVal,digbuf,ret,exp,aFormat.iPlaces,numspace,aFormat,flags); |
|
659 break; |
|
660 case KRealFormatNoExponent: |
|
661 flags=flags | KUseSigFigs; // if flag is NOT set and iTriLen!=0, uses triads |
|
662 ret=doNoExponent(This,digbuf,ret,exp,aFormat.iPlaces,numspace,aFormat,flags); |
|
663 break; |
|
664 case KRealFormatCalculator: |
|
665 flags=(flags | KUseSigFigs) | KDoNotUseTriads | KRealFormatCalculator; |
|
666 ret=doCalculator(This,digbuf,ret,exp,aFormat.iPlaces,maxspace,aFormat,flags); |
|
667 break; |
|
668 default: |
|
669 return(KErrGeneral); |
|
670 } |
|
671 return ProcessErrors(This, ret); |
|
672 } |
|
673 |
|
674 |
|
675 |
|
676 |
|
677 EXPORT_C TRealFormat::TRealFormat() |
|
678 /** |
|
679 Default constructor. |
|
680 |
|
681 The public data members of the constructed object are assigned |
|
682 the following values: |
|
683 |
|
684 TRealFormat::iType - set to KRealFormatGeneral |
|
685 |
|
686 TRealFormat::iWidth - set to KDefaultRealWidth |
|
687 |
|
688 TRealFormat::iPlaces - set to 0 |
|
689 |
|
690 TRealFormat::iPoint - set to the decimal separator character defined in |
|
691 a TLocale object and returned by the DecimalSeparator() |
|
692 member function of that class. |
|
693 |
|
694 TRealFormat::iTriad - set to the character used to delimit groups of three |
|
695 digits in the integer portion of a number; the character |
|
696 is defined in a TLocale object and returned by the |
|
697 ThousandsSeparator() member function of that class. |
|
698 |
|
699 TRealFormat::iTriLen - set to 1 |
|
700 |
|
701 @see TLocale::DecimalSeparator |
|
702 @see TLocale::ThousandsSeparator |
|
703 */ |
|
704 { |
|
705 |
|
706 iType=KRealFormatGeneral; |
|
707 iWidth=KDefaultRealWidth; |
|
708 iPlaces=0; |
|
709 TLocale locale; |
|
710 iPoint=locale.DecimalSeparator(); |
|
711 iTriad=locale.ThousandsSeparator(); |
|
712 iTriLen=1; |
|
713 } |
|
714 |
|
715 |
|
716 |
|
717 |
|
718 EXPORT_C TRealFormat::TRealFormat(TInt aWidth) |
|
719 /** |
|
720 Constructs the object taking the width of the character representation. |
|
721 |
|
722 The remaining public data members of the constructed object are assigned |
|
723 the following values: |
|
724 |
|
725 TRealFormat::iType - set to KRealFormatGeneral |
|
726 |
|
727 TRealFormat::iWidth - set to the aWidth argument |
|
728 |
|
729 TRealFormat::iPlaces - set to 0 |
|
730 |
|
731 TRealFormat::iPoint - set to the decimal separator character defined in |
|
732 a TLocale object and returned by the DecimalSeparator() |
|
733 member function of that class. |
|
734 |
|
735 TRealFormat::iTriad - set to the character used to delimit groups of three |
|
736 digits in the integer portion of a number; the character |
|
737 is defined in a TLocale object and returned by the |
|
738 ThousandsSeparator() member function of that class. |
|
739 |
|
740 TRealFormat::iTriLen - set to 1 |
|
741 |
|
742 @param aWidth The width of the character representation of the real number. |
|
743 |
|
744 @see TLocale::DecimalSeparator |
|
745 @see TLocale::ThousandsSeparator |
|
746 */ |
|
747 { |
|
748 |
|
749 iType=KRealFormatGeneral; |
|
750 iWidth=aWidth; |
|
751 iPlaces=0; |
|
752 TLocale locale; |
|
753 iPoint=locale.DecimalSeparator(); |
|
754 iTriad=locale.ThousandsSeparator(); |
|
755 iTriLen=1; |
|
756 } |
|
757 |
|
758 |
|
759 |
|
760 |
|
761 EXPORT_C TRealFormat::TRealFormat(TInt aWidth,TInt aDecimals) |
|
762 /** |
|
763 Constructs the object taking the width of the character representation |
|
764 and a value which is interpreted as the number of digits to follow |
|
765 the decimal point. |
|
766 |
|
767 The remaining public data members of the constructed object are assigned |
|
768 the following values: |
|
769 |
|
770 TRealFormat::iType - set to KRealFormatFixed |
|
771 |
|
772 TRealFormat::iWidth - set to the aWidth argument |
|
773 |
|
774 TRealFormat::iPlaces - set to the aDecimals argument |
|
775 |
|
776 TRealFormat::iPoint - set to the decimal separator character defined in |
|
777 a TLocale object and returned by the DecimalSeparator() |
|
778 member function of that class. |
|
779 |
|
780 TRealFormat::iTriad - set to the character used to delimit groups of three |
|
781 digits in the integer portion of a number; the character |
|
782 is defined in a TLocale object and returned by the |
|
783 ThousandsSeparator() member function of that class. |
|
784 |
|
785 TRealFormat::iTriLen - set to 1 |
|
786 |
|
787 Note that if the iType data member is changed after construction, aDecimalPlaces |
|
788 may be interpreted as the number of significant digits. For more information, |
|
789 see KRealFormatFixed and the other format types, and KExtraSpaceForSign and the |
|
790 other format flags. |
|
791 |
|
792 @param aWidth The width of the character representation of the real number. |
|
793 @param aDecimals The number of digits to follow the decimal point. |
|
794 |
|
795 @see TLocale::DecimalSeparator() |
|
796 @see TLocale::ThousandsSeparator() |
|
797 @see KRealFormatFixed |
|
798 @see KExtraSpaceForSign |
|
799 */ |
|
800 { |
|
801 |
|
802 iType=KRealFormatFixed; |
|
803 iWidth=aWidth; |
|
804 iPlaces=aDecimals; |
|
805 TLocale locale; |
|
806 iPoint=locale.DecimalSeparator(); |
|
807 iTriad=locale.ThousandsSeparator(); |
|
808 iTriLen=1; |
|
809 } |
|
810 |
|
811 |
|
812 |
|
813 |
|
814 EXPORT_C TInt Math::Round(TReal &aTrg,const TReal &aSrc,TInt aDecimalPlaces) |
|
815 /** |
|
816 Rounds to a specified number of decimal places. |
|
817 |
|
818 The function rounds a number to a given number, n, of decimal places. |
|
819 Rounding may be thought of as multiplying the number by 10 to the power of n, |
|
820 rounding to the nearest integer, and then dividing the result by 10 to |
|
821 the power of n and returning that as the answer. |
|
822 |
|
823 In the process of rounding, numbers ending with .5 are rounded away from zero, |
|
824 so that 1.5 becomes 2, 2.5 becomes 3, -1.5 becomes -2, etc. |
|
825 |
|
826 @param aTrg A reference containing the result. |
|
827 @param aSrc The number to be rounded. |
|
828 @param aDecimalPlaces The number of decimal places to round to: must be |
|
829 zero or positive. |
|
830 |
|
831 @return KErrNone if successful, otherwise another of the system-wide error codes. |
|
832 */ |
|
833 { |
|
834 |
|
835 if (aSrc==0.0) |
|
836 { |
|
837 aTrg=aSrc; |
|
838 return(KErrNone); |
|
839 } |
|
840 TInt ret,exp; |
|
841 TBuf8<0x20> rbuf; |
|
842 if ((ret=fDigLim(rbuf,aSrc,exp,KIEEEDoubleInjectivePrecision))<0) |
|
843 return(ret); |
|
844 if ((exp+aDecimalPlaces)<0) |
|
845 { // Number too small to be rounded |
|
846 aTrg=0; |
|
847 return(KErrNone); |
|
848 } |
|
849 if ((ret-2)<(exp+aDecimalPlaces)) //ret is the string length, including prefixed +/- |
|
850 { // Rounding will have no effect |
|
851 aTrg=aSrc; |
|
852 return(KErrNone); |
|
853 } |
|
854 if ((ret=round(rbuf.Ptr()+1,exp+aDecimalPlaces,EFalse))!=KErrNone) |
|
855 exp++; |
|
856 rbuf.Insert(1,TPtrC8((TText8*)".",1)); |
|
857 rbuf.SetLength(exp+aDecimalPlaces+2); |
|
858 if (!(exp+aDecimalPlaces)) |
|
859 rbuf.Append('0'); |
|
860 // rbuf.AppendFormat(TPtrC8((TText8*)"%c%d",4),'E',exp); |
|
861 rbuf.Append(TChar('E')); |
|
862 rbuf.AppendNum(exp); |
|
863 return(((TLex8)rbuf).Val(aTrg,(TChar)'.')); |
|
864 } |
|
865 |
|
866 EXPORT_C TInt TDes8::Num(TReal aVal,const TRealFormat &aFormat) __SOFTFP |
|
867 /** |
|
868 Converts the specified floating point number into a character representation |
|
869 and copies the conversion into this descriptor, replacing any existing data. |
|
870 |
|
871 The length of this descriptor is set to reflect the new data. |
|
872 |
|
873 The character representation of the real number is dictated by the specified |
|
874 format. |
|
875 |
|
876 Note that the function leaves if the iType data member of the specified |
|
877 TRealFormat object has both an invalid character representation format |
|
878 (i.e. the format type) and invalid format flags. |
|
879 |
|
880 @param aVal The floating point number to be converted. |
|
881 @param aFormat The format of the conversion. |
|
882 |
|
883 @return If the conversion is successful, the length of this descriptor. If |
|
884 the conversion fails, a negative value indicating the cause of failure. |
|
885 In addition, extra information on the cause of the failure may be |
|
886 appended onto this descriptor. The possible values and their meaning |
|
887 are: |
|
888 |
|
889 1.KErrArgument - the supplied floating point number is not a valid |
|
890 number. The three characters NaN are appended to this descriptor. |
|
891 |
|
892 2.KErrOverflow - the number is too large to represent. |
|
893 2.1 For positive overflow, the three characters Inf are appended |
|
894 to this descriptor. |
|
895 2.2 For negative overflow, the four characters -Inf are appended |
|
896 to this descriptor. |
|
897 |
|
898 3.KErrUnderflow - the number is too small to represent. |
|
899 3.1 For positive underflow, the three characters Inf are appended |
|
900 to this descriptor. |
|
901 3.2 For negative underflow, the four characters -Inf are appended |
|
902 to this descriptor. |
|
903 |
|
904 4.KErrGeneral - the conversion cannot be completed. There are a |
|
905 number of possible reasons for this, but the two most common |
|
906 are: |
|
907 4.1 the maximum number of characters necessary to represent the number, |
|
908 as defined in the TRealFormat object, is greater than the maximum |
|
909 length of this descriptor |
|
910 4.2 the character representation format (i.e. the format type), as |
|
911 defined in the TRealFormat object is not recognised. |
|
912 |
|
913 @see TRealFormat::iType |
|
914 */ |
|
915 { |
|
916 |
|
917 Zero(); |
|
918 return(rtob(this,aVal,aFormat)); |
|
919 } |
|
920 |
|
921 EXPORT_C TInt TDes8::AppendNum(TReal aVal,const TRealFormat &aFormat) __SOFTFP |
|
922 /** |
|
923 Converts the specified floating point number into a character representation |
|
924 and appends the conversion onto the end of this descriptor's data. |
|
925 |
|
926 The length of this descriptor is incremented to reflect the new content. |
|
927 |
|
928 The character representation of the real number is dictated by the specified |
|
929 format. |
|
930 |
|
931 @param aVal The floating point number to be converted. |
|
932 @param aFormat The format of the conversion. |
|
933 |
|
934 @return If the conversion is successful, the length of this descriptor. If |
|
935 the conversion fails, a negative value indicating the cause of failure. |
|
936 In addition, extra information on the cause of the failure may be |
|
937 appended onto this descriptor. The possible values and their meaning |
|
938 are: |
|
939 |
|
940 1.KErrArgument - the supplied floating point number is not a valid |
|
941 number. The three characters NaN are appended to this descriptor. |
|
942 |
|
943 2.KErrOverflow - the number is too large to represent. |
|
944 2.1 For positive overflow, the three characters Inf are appended |
|
945 to this descriptor. |
|
946 2.2 For negative overflow, the four characters -Inf are appended |
|
947 to this descriptor. |
|
948 |
|
949 3.KErrUnderflow - the number is too small to represent. |
|
950 3.1 For positive underflow, the three characters Inf are appended |
|
951 to this descriptor. |
|
952 3.2 For negative underflow, the four characters -Inf are appended |
|
953 to this descriptor. |
|
954 |
|
955 4.KErrGeneral - the conversion cannot be completed. There are a |
|
956 number of possible reasons for this, but the two most common |
|
957 are: |
|
958 4.1 the maximum number of characters necessary to represent the number, |
|
959 as defined in the TRealFormat object, is greater than the maximum |
|
960 length of this descriptor |
|
961 4.2 the character representation format (i.e. the format type), as |
|
962 defined in the TRealFormat object is not recognised |
|
963 */ |
|
964 { |
|
965 |
|
966 return(rtob(this,aVal,aFormat)); |
|
967 } |
|
968 |
|
969 EXPORT_C TInt TDes16::Num(TReal aVal,const TRealFormat &aFormat) __SOFTFP |
|
970 /** |
|
971 Converts the specified floating point number into a character representation |
|
972 and copies the conversion into this descriptor, replacing any existing data. |
|
973 |
|
974 The length of this descriptor is set to reflect the new data. |
|
975 |
|
976 The character representation of the real number is dictated by the specified |
|
977 format. |
|
978 |
|
979 Note that the function leaves if the iType data member of the specified |
|
980 TRealFormat object has both an invalid character representation format |
|
981 (i.e. the format type) and invalid format flags. |
|
982 |
|
983 @param aVal The floating point number to be converted. |
|
984 @param aFormat The format of the conversion. |
|
985 |
|
986 @return If the conversion is successful, the length of this descriptor. If |
|
987 the conversion fails, a negative value indicating the cause of failure. |
|
988 In addition, extra information on the cause of the failure may be |
|
989 appended onto this descriptor. The possible values and their meaning |
|
990 are: |
|
991 |
|
992 1.KErrArgument - the supplied floating point number is not a valid |
|
993 number. The three characters NaN are appended to this descriptor. |
|
994 |
|
995 2.KErrOverflow - the number is too large to represent. |
|
996 2.1 For positive overflow, the three characters Inf are appended |
|
997 to this descriptor. |
|
998 2.2 For negative overflow, the four characters -Inf are appended |
|
999 to this descriptor. |
|
1000 |
|
1001 3.KErrUnderflow - the number is too small to represent. |
|
1002 3.1 For positive underflow, the three characters Inf are appended |
|
1003 to this descriptor. |
|
1004 3.2 For negative underflow, the four characters -Inf are appended |
|
1005 to this descriptor. |
|
1006 |
|
1007 4.KErrGeneral - the conversion cannot be completed. There are a |
|
1008 number of possible reasons for this, but the two most common |
|
1009 are: |
|
1010 4.1 the maximum number of characters necessary to represent the number, |
|
1011 as defined in the TRealFormat object, is greater than the maximum |
|
1012 length of this descriptor |
|
1013 4.2 the character representation format (i.e. the format type), as |
|
1014 defined in the TRealFormat object is not recognised. |
|
1015 |
|
1016 @see TRealFormat::iType |
|
1017 */ |
|
1018 { |
|
1019 |
|
1020 Zero(); |
|
1021 return (AppendNum(aVal,aFormat)); |
|
1022 } |
|
1023 |
|
1024 EXPORT_C TInt TDes16::AppendNum(TReal aVal,const TRealFormat &aFormat) __SOFTFP |
|
1025 /** |
|
1026 Converts the specified floating point number into a character representation |
|
1027 and appends the conversion onto the end of this descriptor's data. |
|
1028 |
|
1029 The length of this descriptor is incremented to reflect the new content. |
|
1030 |
|
1031 The character representation of the real number is dictated by the specified |
|
1032 format. |
|
1033 |
|
1034 @param aVal The floating point number to be converted. |
|
1035 @param aFormat The format of the conversion. |
|
1036 |
|
1037 @return If the conversion is successful, the length of this descriptor. If |
|
1038 the conversion fails, a negative value indicating the cause of failure. |
|
1039 In addition, extra information on the cause of the failure may be |
|
1040 appended onto this descriptor. The possible values and their meaning |
|
1041 are: |
|
1042 |
|
1043 1.KErrArgument - the supplied floating point number is not a valid |
|
1044 number. The three characters NaN are appended to this descriptor. |
|
1045 |
|
1046 2.KErrOverflow - the number is too large to represent. |
|
1047 2.1 For positive overflow, the three characters Inf are appended |
|
1048 to this descriptor. |
|
1049 2.2 For negative overflow, the four characters -Inf are appended |
|
1050 to this descriptor. |
|
1051 |
|
1052 3.KErrUnderflow - the number is too small to represent. |
|
1053 3.1 For positive underflow, the three characters Inf are appended |
|
1054 to this descriptor. |
|
1055 3.2 For negative underflow, the four characters -Inf are appended |
|
1056 to this descriptor. |
|
1057 |
|
1058 4.KErrGeneral - the conversion cannot be completed. There are a |
|
1059 number of possible reasons for this, but the two most common |
|
1060 are: |
|
1061 4.1 the maximum number of characters necessary to represent the number, |
|
1062 as defined in the TRealFormat object, is greater than the maximum |
|
1063 length of this descriptor |
|
1064 4.2 the character representation format (i.e. the format type), as |
|
1065 defined in the TRealFormat object is not recognised |
|
1066 */ |
|
1067 { |
|
1068 |
|
1069 HBufC8 *temp=HBufC8::New(MaxLength()); |
|
1070 if (temp==NULL) |
|
1071 return(KErrNoMemory); |
|
1072 TPtr8 p(temp->Des()); |
|
1073 TInt ret=rtob(&p,aVal,aFormat); |
|
1074 const TText8 *pTemp=temp->Ptr(); |
|
1075 for (TInt ii=temp->Length();ii>0;ii--) |
|
1076 Append(*pTemp++); |
|
1077 if (ret>0) |
|
1078 ret=Length(); |
|
1079 User::Free(temp); |
|
1080 return (ret); |
|
1081 } |