Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\euser\maths\um_rtod.cpp
22 #define KNeedsRounding 0x1000
23 #if (KRealFormatTypeFlagsMask| KRealFormatTypesMask) & KNeedsRounding
24 #error KNeedsRounding already uses 0x1000
27 const TInt KMinThreeDigitExponent=100;
30 _LIT8(KLit8Minus,"-");
32 _LIT8(KLit8Inf,"Inf");
33 _LIT8(KLit8Nan,"NaN");
35 LOCAL_C TInt round(const TText8* aBuf, const TInt aLen, TBool aExact)
37 // Round number in buffer depending on digit at aBuf[aLen].
38 // Return value is carry from most significant digit.
41 __ASSERT_DEBUG(aLen>=0,Panic(EMathUnexpectedError1));
42 TText8* pB=(TText8*)aBuf+aLen;
44 return 0; // round down
45 if (*pB=='5' && aExact && aLen>0 && !(pB[-1]&1))
46 return 0; // exactly half way - round to even
58 // carry propagates to exponent
65 TUint mult10(TUint64& a)
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.
71 const TUint64 ten = 10;
73 Math::UMul64(a, ten, high, a);
74 return static_cast<TUint>(high);
77 LOCAL_C TInt fDigLim(TDes8& aTrg, const TReal& aSrc, TInt& aExp, TInt aPrec)
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.
83 // AnnW, November 1996 - changed to handle all numbers in TReal64/96 range.
85 // The first character in aBuf is one of:
87 // '0' - indicates that aSrc is exactly zero.
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.
93 // '-' - indicates a negative mantissa and is otherwise the same as for '+'.
105 else // sets sign in all cases, including specials
106 aTrg=(x.iSign ? KLit8Minus() : KLit8Plus());
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)
124 Math::MultPow10X(x,-1); // if x>=1, multiply x by 10^-1 and increment e
126 // relative error now <= 11 units of 0.5LSB
128 TUint64 mantissa = MAKE_TUINT64(x.iMantHi, x.iMantLo);
131 mantissa >>= (0x7ffe - x.iExp); // shift to make exponent 0x7ffe, i.e. mantissa in range 0.1<=m<1
134 if (prec > KIEEEDoubleInjectivePrecision)
135 prec = KIEEEDoubleInjectivePrecision;
137 while ( mantissa && (aTrg.Length() < (prec + 2)) )
139 TUint d = mult10(mantissa);
142 if (aTrg.Length()>=prec+2)
144 e+=round(aTrg.Ptr()+1,prec,mantissa==0);
145 aTrg.SetLength(prec+1);
148 return aTrg.Length();
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)
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.
159 // AnnW, November 1996 - changed to be able to take three-figure exponents if allowed by flags.
165 TInt useSigFigs=flags & KUseSigFigs;
166 TInt nDig=(useSigFigs ? Min(aNumPlcs,afDigLimSize) : aNumPlcs+1);
167 TInt threeDigitExp=flags & KAllowThreeDigitExp;
169 if ((flags & KNeedsRounding) && afDigLimSize>nDig)
170 aExp+=round(aDigBuf.Ptr()+1,nDig,EFalse);
172 if (useSigFigs) // discard trailing zeros
174 while(nDig>1 && aDigBuf[nDig]=='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
188 expSpace=(Abs(aExp)>=KMinThreeDigitExponent)?5:4;
192 err=(aExp<=-KMinThreeDigitExponent ? KErrUnderflow : (aExp>=KMinThreeDigitExponent ? KErrOverflow : KErrNone));
198 // Check that number will fit in aNumSpace
199 if (aNumSpace<(expSpace+nDig+(nDig>1?1:0)))
200 // exponent + significant figures + point(if necessary)
204 if (aDigBuf[0]=='0') // number to be converted is 0
207 if (nDig>1 && !useSigFigs)
209 This->Append(aPoint);
210 This->AppendFill('0',aNumPlcs);
215 This->Append(TChar(aDigBuf[1]));
218 This->Append(aPoint);
219 for (TInt ii=2; ii<=nDig; ii++)
223 This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii]:'0'));
225 // do not pad with zeros
226 This->Append(TChar(aDigBuf[ii]));
242 if (threeDigitExp && aExp>99)
244 This->Append(aExp/100+'0');
251 This->Append(tempExp/10+'0');
252 This->Append(tempExp%10+'0');
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)
259 // Convert the intermediate number represented in aDigBuf into its fixed representation and
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.
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]!='-'))
275 TInt roundOffset = aNumDecPlcs+aExp;
276 if (roundOffset>=0 && afDigLimSize>roundOffset && (flags & KNeedsRounding))
277 aExp+=round(aDigBuf.Ptr()+1,roundOffset,EFalse);
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)
282 err=(aExp>0 ? KErrOverflow : KErrGeneral);
286 if (aExp<=0) // hence number is of the form 0.NNNN
292 TInt nDig=aNumDecPlcs-aExp; // number of digits required from aDigBuf
293 This->Append(aFormat.iPoint);
294 if (aExp>aNumDecPlcs)
296 This->AppendFill('0',aExp);
299 for (TInt ii=1; ii<nDig+1; ii++)
300 This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii]:'0'));
303 else // no decimal places
307 This->Delete(0,2); // delete -0 from This
312 else // aExp > 0 hence number is of the form NNNN.NNNN
314 for (TInt jj=1,ii=aExp; ii; ii--,jj++)
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]));
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'));
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)
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.
343 TInt doNotUseTriads=flags & KDoNotUseTriads;
344 TInt numSpace=aNumSpace;
345 if ((flags & KExtraSpaceForSign) && (aDigBuf[0]!='-'))
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))
355 if (aDigBuf[0]=='0') // do zero first (numSpace>=0 so OK)
359 // check for overflow/underflow
360 if ((aExp+nTriadSeps)>numSpace)
361 return(KErrOverflow);
363 return(KErrUnderflow);
365 if ((flags&(TUint)KRealFormatTypesMask)!=(TUint)KRealFormatCalculator && aExp>aMaxSigFigs)
366 return(KErrOverflow);
368 TInt nDecPlcs=nDig-aExp;
369 while(nDecPlcs>0 && aDigBuf[nDig]=='0')
370 { // discard trailing zeros (already done in calculator)
375 if (aExp<=0) // hence number is of the form 0.NNNN
379 // if (nDecPlcs<=0) do nothing
382 This->Append(aFormat.iPoint);
383 This->AppendFill('0',aExp);
384 for (TInt ii=1; ii<=nDig; ii++)
385 This->Append(TChar(aDigBuf[ii]));
388 else // aExp > 0 hence number is of the form NNNN.NNNN
390 for (TInt jj=1,ii=aExp; ii; ii--,jj++)
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'));
398 This->Append(aFormat.iPoint);
399 for (TInt ii=aExp+1; ii<=nDig; ii++)
400 This->Append(TChar(aDigBuf[ii]));
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
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
414 // Annw, November 1996 - changed to allow space for sign in fixed mode, three-figure exponent.
417 TBool rounded=((flags & KNeedsRounding)==0);
418 TInt nDig=aDigBuf.Length()-1; // no of digits without sign
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]!='-'))
425 if (fixedNumSpace<=0)
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.
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
439 if (aNumSpace<5 || (aExp>=-2 && aExp<=fixedNumSpace))
441 type=KRealFormatFixed;
443 // if there is at least one digit before decimal point or no. is zero
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;
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;
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)
474 // in any case, aNumDecPlcs is one less that the number of digits,
475 // i.e. one digit before the point
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))
485 while(aNumDecPlcs>0 && aDigBuf[nDig]=='0')
486 { // discard trailing zeros
490 flags=flags & ~KNeedsRounding;
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));
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)
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
507 TBool threeDigExp=((flags & KAllowThreeDigitExp)!=0);
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)))
514 // now discard trailing zeros
515 TInt nDig=afDigLimSize;
516 while(nDig>1 && aDigBuf[nDig]=='0')
521 TInt maxDig=Min(aMaxSigFigs,nDig); // max digs available
522 TBool rounded=((flags & KNeedsRounding)==0);
531 // use no exponent for all numbers which will not use > aMaxSigFigs digits
532 if (aExp>aMaxSigFigs || (aExp<=0 && (1-aExp+nDig)>aMaxSigFigs))
536 type=KRealFormatNoExponent;
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));
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))
556 TInt numSpace=aMaxSpace-(aDigBuf[0]=='-'?1:0);
557 flags=flags & ~KNeedsRounding;
559 if (type==KRealFormatExponent)
560 return(doExponent(This,aDigBuf,afDigLimSize,aExp,nDig,numSpace,(TText)aFormat.iPoint,flags));
563 flags|=KExtraSpaceForSign;
564 return(doNoExponent(This,aDigBuf,afDigLimSize,aExp,nDig,numSpace,aFormat,flags));
568 TInt ProcessErrors(TDes8* aDes, TInt anError)
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());
581 LOCAL_C TInt rtob(TDes8 *This,TReal aVal,const TRealFormat &aFormat) __SOFTFP
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.
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.
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
608 if (aFormat.iWidth>This->MaxLength())
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();
627 if (digbuf[0]=='-' && ret!=KErrArgument) // NaN has no sign
633 return ProcessErrors(This, ret);
641 if (aFormat.iType & ~KRealFormatTypesMask & ~KRealFormatTypeFlagsMask)
643 type=aFormat.iType & KRealFormatTypesMask;
644 flags=((aFormat.iType & KRealFormatTypeFlagsMask)| KNeedsRounding);
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);
653 case KRealFormatExponent:
654 ret=doExponent(This,digbuf,ret,exp,aFormat.iPlaces,numspace,(TText)aFormat.iPoint,flags);
656 case KRealFormatGeneral:
657 flags=(flags & ~KUseSigFigs) | KDoNotUseTriads;
658 ret=doGeneral(This,aVal,digbuf,ret,exp,aFormat.iPlaces,numspace,aFormat,flags);
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);
664 case KRealFormatCalculator:
665 flags=(flags | KUseSigFigs) | KDoNotUseTriads | KRealFormatCalculator;
666 ret=doCalculator(This,digbuf,ret,exp,aFormat.iPlaces,maxspace,aFormat,flags);
671 return ProcessErrors(This, ret);
677 EXPORT_C TRealFormat::TRealFormat()
681 The public data members of the constructed object are assigned
682 the following values:
684 TRealFormat::iType - set to KRealFormatGeneral
686 TRealFormat::iWidth - set to KDefaultRealWidth
688 TRealFormat::iPlaces - set to 0
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.
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.
699 TRealFormat::iTriLen - set to 1
701 @see TLocale::DecimalSeparator
702 @see TLocale::ThousandsSeparator
706 iType=KRealFormatGeneral;
707 iWidth=KDefaultRealWidth;
710 iPoint=locale.DecimalSeparator();
711 iTriad=locale.ThousandsSeparator();
718 EXPORT_C TRealFormat::TRealFormat(TInt aWidth)
720 Constructs the object taking the width of the character representation.
722 The remaining public data members of the constructed object are assigned
723 the following values:
725 TRealFormat::iType - set to KRealFormatGeneral
727 TRealFormat::iWidth - set to the aWidth argument
729 TRealFormat::iPlaces - set to 0
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.
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.
740 TRealFormat::iTriLen - set to 1
742 @param aWidth The width of the character representation of the real number.
744 @see TLocale::DecimalSeparator
745 @see TLocale::ThousandsSeparator
749 iType=KRealFormatGeneral;
753 iPoint=locale.DecimalSeparator();
754 iTriad=locale.ThousandsSeparator();
761 EXPORT_C TRealFormat::TRealFormat(TInt aWidth,TInt aDecimals)
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
767 The remaining public data members of the constructed object are assigned
768 the following values:
770 TRealFormat::iType - set to KRealFormatFixed
772 TRealFormat::iWidth - set to the aWidth argument
774 TRealFormat::iPlaces - set to the aDecimals argument
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.
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.
785 TRealFormat::iTriLen - set to 1
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
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.
795 @see TLocale::DecimalSeparator()
796 @see TLocale::ThousandsSeparator()
797 @see KRealFormatFixed
798 @see KExtraSpaceForSign
802 iType=KRealFormatFixed;
806 iPoint=locale.DecimalSeparator();
807 iTriad=locale.ThousandsSeparator();
814 EXPORT_C TInt Math::Round(TReal &aTrg,const TReal &aSrc,TInt aDecimalPlaces)
816 Rounds to a specified number of decimal places.
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.
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.
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
831 @return KErrNone if successful, otherwise another of the system-wide error codes.
842 if ((ret=fDigLim(rbuf,aSrc,exp,KIEEEDoubleInjectivePrecision))<0)
844 if ((exp+aDecimalPlaces)<0)
845 { // Number too small to be rounded
849 if ((ret-2)<(exp+aDecimalPlaces)) //ret is the string length, including prefixed +/-
850 { // Rounding will have no effect
854 if ((ret=round(rbuf.Ptr()+1,exp+aDecimalPlaces,EFalse))!=KErrNone)
856 rbuf.Insert(1,TPtrC8((TText8*)".",1));
857 rbuf.SetLength(exp+aDecimalPlaces+2);
858 if (!(exp+aDecimalPlaces))
860 // rbuf.AppendFormat(TPtrC8((TText8*)"%c%d",4),'E',exp);
861 rbuf.Append(TChar('E'));
863 return(((TLex8)rbuf).Val(aTrg,(TChar)'.'));
866 EXPORT_C TInt TDes8::Num(TReal aVal,const TRealFormat &aFormat) __SOFTFP
868 Converts the specified floating point number into a character representation
869 and copies the conversion into this descriptor, replacing any existing data.
871 The length of this descriptor is set to reflect the new data.
873 The character representation of the real number is dictated by the specified
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.
880 @param aVal The floating point number to be converted.
881 @param aFormat The format of the conversion.
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
889 1.KErrArgument - the supplied floating point number is not a valid
890 number. The three characters NaN are appended to this descriptor.
892 2.KErrOverflow - the number is too large to represent.
893 2.1 For positive overflow, the three characters Inf are appended
895 2.2 For negative overflow, the four characters -Inf are appended
898 3.KErrUnderflow - the number is too small to represent.
899 3.1 For positive underflow, the three characters Inf are appended
901 3.2 For negative underflow, the four characters -Inf are appended
904 4.KErrGeneral - the conversion cannot be completed. There are a
905 number of possible reasons for this, but the two most common
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.
913 @see TRealFormat::iType
918 return(rtob(this,aVal,aFormat));
921 EXPORT_C TInt TDes8::AppendNum(TReal aVal,const TRealFormat &aFormat) __SOFTFP
923 Converts the specified floating point number into a character representation
924 and appends the conversion onto the end of this descriptor's data.
926 The length of this descriptor is incremented to reflect the new content.
928 The character representation of the real number is dictated by the specified
931 @param aVal The floating point number to be converted.
932 @param aFormat The format of the conversion.
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
940 1.KErrArgument - the supplied floating point number is not a valid
941 number. The three characters NaN are appended to this descriptor.
943 2.KErrOverflow - the number is too large to represent.
944 2.1 For positive overflow, the three characters Inf are appended
946 2.2 For negative overflow, the four characters -Inf are appended
949 3.KErrUnderflow - the number is too small to represent.
950 3.1 For positive underflow, the three characters Inf are appended
952 3.2 For negative underflow, the four characters -Inf are appended
955 4.KErrGeneral - the conversion cannot be completed. There are a
956 number of possible reasons for this, but the two most common
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
966 return(rtob(this,aVal,aFormat));
969 EXPORT_C TInt TDes16::Num(TReal aVal,const TRealFormat &aFormat) __SOFTFP
971 Converts the specified floating point number into a character representation
972 and copies the conversion into this descriptor, replacing any existing data.
974 The length of this descriptor is set to reflect the new data.
976 The character representation of the real number is dictated by the specified
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.
983 @param aVal The floating point number to be converted.
984 @param aFormat The format of the conversion.
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
992 1.KErrArgument - the supplied floating point number is not a valid
993 number. The three characters NaN are appended to this descriptor.
995 2.KErrOverflow - the number is too large to represent.
996 2.1 For positive overflow, the three characters Inf are appended
998 2.2 For negative overflow, the four characters -Inf are appended
1001 3.KErrUnderflow - the number is too small to represent.
1002 3.1 For positive underflow, the three characters Inf are appended
1004 3.2 For negative underflow, the four characters -Inf are appended
1007 4.KErrGeneral - the conversion cannot be completed. There are a
1008 number of possible reasons for this, but the two most common
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.
1016 @see TRealFormat::iType
1021 return (AppendNum(aVal,aFormat));
1024 EXPORT_C TInt TDes16::AppendNum(TReal aVal,const TRealFormat &aFormat) __SOFTFP
1026 Converts the specified floating point number into a character representation
1027 and appends the conversion onto the end of this descriptor's data.
1029 The length of this descriptor is incremented to reflect the new content.
1031 The character representation of the real number is dictated by the specified
1034 @param aVal The floating point number to be converted.
1035 @param aFormat The format of the conversion.
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
1043 1.KErrArgument - the supplied floating point number is not a valid
1044 number. The three characters NaN are appended to this descriptor.
1046 2.KErrOverflow - the number is too large to represent.
1047 2.1 For positive overflow, the three characters Inf are appended
1049 2.2 For negative overflow, the four characters -Inf are appended
1052 3.KErrUnderflow - the number is too small to represent.
1053 3.1 For positive underflow, the three characters Inf are appended
1055 3.2 For negative underflow, the four characters -Inf are appended
1058 4.KErrGeneral - the conversion cannot be completed. There are a
1059 number of possible reasons for this, but the two most common
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
1069 HBufC8 *temp=HBufC8::New(MaxLength());
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--)