--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/maths/um_rtod.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1081 @@
+// 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_rtod.cpp
+//
+//
+
+#include "um_std.h"
+
+#include <e32debug.h>
+
+#define KNeedsRounding 0x1000
+#if (KRealFormatTypeFlagsMask| KRealFormatTypesMask) & KNeedsRounding
+ #error KNeedsRounding already uses 0x1000
+#endif
+
+const TInt KMinThreeDigitExponent=100;
+
+_LIT8(KLit8Plus,"+");
+_LIT8(KLit8Minus,"-");
+_LIT8(KLit8Zero,"0");
+_LIT8(KLit8Inf,"Inf");
+_LIT8(KLit8Nan,"NaN");
+
+LOCAL_C TInt round(const TText8* aBuf, const TInt aLen, TBool aExact)
+//
+// Round number in buffer depending on digit at aBuf[aLen].
+// Return value is carry from most significant digit.
+//
+ {
+ __ASSERT_DEBUG(aLen>=0,Panic(EMathUnexpectedError1));
+ TText8* pB=(TText8*)aBuf+aLen;
+ if (*pB<'5')
+ return 0; // round down
+ if (*pB=='5' && aExact && aLen>0 && !(pB[-1]&1))
+ return 0; // exactly half way - round to even
+ while(--pB>=aBuf)
+ {
+ TText8 d=*pB;
+ if (d<'9')
+ {
+ ++d;
+ *pB=d;
+ return 0;
+ }
+ *pB='0';
+ }
+ // carry propagates to exponent
+ *++pB='1';
+ if (aLen>0)
+ pB[aLen]='0';
+ return 1;
+ }
+
+TUint mult10(TUint64& a)
+//
+// Multiply a 64-bit binary fraction in a (MSB=2^-1) by 10
+// Return the fractional part in a, the integer part in the return value.
+//
+ {
+ const TUint64 ten = 10;
+ TUint64 high;
+ Math::UMul64(a, ten, high, a);
+ return static_cast<TUint>(high);
+ }
+
+LOCAL_C TInt fDigLim(TDes8& aTrg, const TReal& aSrc, TInt& aExp, TInt aPrec)
+//
+// Convert the TReal at address aSrc to a decimal form suitable for use by a
+// formatting routine. Writes the result into the descriptor at aTrg and the
+// exponent in aExp. Returns the length of the string or a negative error number.
+//
+// AnnW, November 1996 - changed to handle all numbers in TReal64/96 range.
+//
+// The first character in aBuf is one of:
+//
+// '0' - indicates that aSrc is exactly zero.
+//
+// '+' - indicates a positive number and is followed by between 1 and KMaxPrecision
+// decimal digits representing a mantissa in the range 0.1 to less than 1.0 which
+// corresponds to the decimal exponent returned in aExp.
+//
+// '-' - indicates a negative mantissa and is otherwise the same as for '+'.
+//
+ {
+
+ TRealX x;
+ TInt r=x.Set(aSrc);
+
+ if (x.IsZero())
+ {
+ aTrg=KLit8Zero();
+ return 1;
+ }
+ else // sets sign in all cases, including specials
+ aTrg=(x.iSign ? KLit8Minus() : KLit8Plus());
+
+ if (r!=KErrNone)
+ return r;
+
+ x.iSign=0;
+ TInt e=TInt(x.iExp)-0x7fff; // 2^e<=Abs(x)<2^(e+1)
+ e*=19728; // log10(2)*65536 = 19728.301796...
+ // max error due to omission of fractional part is 9889 (towards zero)
+ e-=9889; // account for error, e may be too small by up to 19778
+ // Now have 10^(e/65536)<=Abs(x)<4.007*10^(e/65536)
+ e>>=16; // Divide by 65536 - this always rounds towards -infinity
+ // Now have 10^e<=Abs(x)<40.07*10^e
+ e+=1; // Now have 0.1<=Abs(x)/10^e<4.07
+ Math::MultPow10X(x,-e); // x*=10^-e so now 0.1<=x<4.07 (rel error <= 8 units of 0.5LSB)
+ if (x.iExp>=0x7fff)
+ {
+ ++e;
+ Math::MultPow10X(x,-1); // if x>=1, multiply x by 10^-1 and increment e
+ }
+ // relative error now <= 11 units of 0.5LSB
+
+ TUint64 mantissa = MAKE_TUINT64(x.iMantHi, x.iMantLo);
+
+ if (x.iExp<0x7ffe)
+ mantissa >>= (0x7ffe - x.iExp); // shift to make exponent 0x7ffe, i.e. mantissa in range 0.1<=m<1
+
+ TInt prec = aPrec;
+ if (prec > KIEEEDoubleInjectivePrecision)
+ prec = KIEEEDoubleInjectivePrecision;
+
+ while ( mantissa && (aTrg.Length() < (prec + 2)) )
+ {
+ TUint d = mult10(mantissa);
+ aTrg.Append(d+'0');
+ }
+ if (aTrg.Length()>=prec+2)
+ {
+ e+=round(aTrg.Ptr()+1,prec,mantissa==0);
+ aTrg.SetLength(prec+1);
+ }
+ aExp=e;
+ return aTrg.Length();
+ }
+
+LOCAL_C TInt doExponent(TDes8* This, TDes8& aDigBuf, const TInt afDigLimSize, TInt aExp,
+ const TInt aNumPlcs, const TInt aNumSpace, const TText aPoint, const TUint flags)
+//
+// Convert the intermediate number represented in aDigBuf into its exponential representation
+// and place into aTrg.
+// This representation ensures that numbers are displayed to aNumDecPlcs+1 significant figures,
+// but this is NOT a constant value in KTRealFormatGeneral mode.
+//
+// AnnW, November 1996 - changed to be able to take three-figure exponents if allowed by flags.
+//
+ {
+
+ TInt err;
+ TInt expSpace;
+ TInt useSigFigs=flags & KUseSigFigs;
+ TInt nDig=(useSigFigs ? Min(aNumPlcs,afDigLimSize) : aNumPlcs+1);
+ TInt threeDigitExp=flags & KAllowThreeDigitExp;
+
+ if ((flags & KNeedsRounding) && afDigLimSize>nDig)
+ aExp+=round(aDigBuf.Ptr()+1,nDig,EFalse);
+
+ if (useSigFigs) // discard trailing zeros
+ {
+ while(nDig>1 && aDigBuf[nDig]=='0')
+ {
+ nDig--;
+ }
+ }
+
+ if (aDigBuf[0]!='0')
+ // 100.5 is stored in aDigBuf as +1005 with and exp of 3, but it is to be displayed
+ // as 1.005 so exp must be decremented to 2
+ aExp--;
+
+ // Added by AnnW
+ if (threeDigitExp)
+ {
+ expSpace=(Abs(aExp)>=KMinThreeDigitExponent)?5:4;
+ }
+ else
+ {
+ err=(aExp<=-KMinThreeDigitExponent ? KErrUnderflow : (aExp>=KMinThreeDigitExponent ? KErrOverflow : KErrNone));
+ if (err!=KErrNone)
+ return(err);
+ expSpace=4;
+ }
+
+ // Check that number will fit in aNumSpace
+ if (aNumSpace<(expSpace+nDig+(nDig>1?1:0)))
+ // exponent + significant figures + point(if necessary)
+ return(KErrGeneral);
+ // end of added
+
+ if (aDigBuf[0]=='0') // number to be converted is 0
+ {
+ This->Append('0');
+ if (nDig>1 && !useSigFigs)
+ {
+ This->Append(aPoint);
+ This->AppendFill('0',aNumPlcs);
+ }
+ }
+ else
+ {
+ This->Append(TChar(aDigBuf[1]));
+ if (nDig>1)
+ {
+ This->Append(aPoint);
+ for (TInt ii=2; ii<=nDig; ii++)
+ {
+ if (!useSigFigs)
+ // pad with zeros
+ This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii]:'0'));
+ else
+ // do not pad with zeros
+ This->Append(TChar(aDigBuf[ii]));
+ }
+ }
+ }
+
+ This->Append('E');
+ if (aExp<0)
+ {
+ aExp=-aExp;
+ This->Append('-');
+ }
+ else
+ This->Append('+');
+
+ // Added by AnnW
+ TInt tempExp;
+ if (threeDigitExp && aExp>99)
+ {
+ This->Append(aExp/100+'0');
+ tempExp=aExp%100;
+ }
+ else
+ tempExp = aExp;
+ // end of added
+
+ This->Append(tempExp/10+'0');
+ This->Append(tempExp%10+'0');
+ return(KErrNone);
+ }
+
+LOCAL_C TInt doFixed(TDes8 *This,TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp,const TInt aNumDecPlcs,
+ const TInt aNumSpace,const TRealFormat &aFormat,const TUint flags)
+//
+// Convert the intermediate number represented in aDigBuf into its fixed representation and
+// place into aTrg
+//
+// AnnW, November 1996 - changed to allow extra space to be left for potential sign, so that
+// positive and negative numbers of the same exponent are displayed to the same precision.
+//
+ {
+
+ TInt err;
+ TInt doNotUseTriads=flags & KDoNotUseTriads;
+ TInt newNumSpace=aNumSpace;
+ // To allow positive and negative numbers with the same exponent to have the same number of
+ // significant figures.
+ if ((flags & KExtraSpaceForSign) && (aDigBuf[0]!='-'))
+ newNumSpace--;
+
+ TInt roundOffset = aNumDecPlcs+aExp;
+ if (roundOffset>=0 && afDigLimSize>roundOffset && (flags & KNeedsRounding))
+ aExp+=round(aDigBuf.Ptr()+1,roundOffset,EFalse);
+
+ if (newNumSpace<((aExp>0?aExp:1)+(aNumDecPlcs?aNumDecPlcs+1:0)+(!doNotUseTriads && aFormat.iTriLen && (aExp>(TInt)aFormat.iTriLen)?(aExp-1)/3:0)))
+ // exponent +ve and space < space needed for (digits before point + point + decimal places + triads)
+ {
+ err=(aExp>0 ? KErrOverflow : KErrGeneral);
+ return(err);
+ }
+
+ if (aExp<=0) // hence number is of the form 0.NNNN
+ {
+ This->Append('0');
+ if (aNumDecPlcs)
+ {
+ aExp=-aExp;
+ TInt nDig=aNumDecPlcs-aExp; // number of digits required from aDigBuf
+ This->Append(aFormat.iPoint);
+ if (aExp>aNumDecPlcs)
+ aExp=aNumDecPlcs;
+ This->AppendFill('0',aExp);
+ if (nDig>0)
+ {
+ for (TInt ii=1; ii<nDig+1; ii++)
+ This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii]:'0'));
+ }
+ }
+ else // no decimal places
+ {
+ if (aDigBuf[0]=='-')
+ {
+ This->Delete(0,2); // delete -0 from This
+ This->Append('0');
+ }
+ }
+ }
+ else // aExp > 0 hence number is of the form NNNN.NNNN
+ {
+ for (TInt jj=1,ii=aExp; ii; ii--,jj++)
+ {
+ if (!doNotUseTriads && aFormat.iTriLen && aExp>(TInt)aFormat.iTriLen && !(ii%3) && ii!=aExp)
+ This->Append(aFormat.iTriad);
+ This->Append(TChar(jj>=aDigBuf.Length() ? '0' : aDigBuf[jj]));
+ }
+ if (aNumDecPlcs>0)
+ {
+ This->Append(aFormat.iPoint);
+ for (TInt ii=aExp+1; ii<aNumDecPlcs+aExp+1; ii++)
+ This->Append(TChar(ii<aDigBuf.Length() ? aDigBuf[ii] : '0'));
+ }
+ }
+
+ return(KErrNone);
+ }
+
+LOCAL_C TInt doNoExponent(TDes8 *This, TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp,
+ const TInt aMaxSigFigs,const TInt aNumSpace, const TRealFormat &aFormat,const TUint flags)
+//
+// Added by AnnW, November 1996
+// Convert the intermediate number represented in aDigBuf into its no exponent representation
+// and place into aTrg
+// Changed April 1997 - If there is not enough space for the number of s.f., zeros, points, triads,
+// etc, then the number of significant figs is reduced to fit. Overflow if too big to fit and
+// underflow if no significance can be seen.
+//
+ {
+
+ TInt doNotUseTriads=flags & KDoNotUseTriads;
+ TInt numSpace=aNumSpace;
+ if ((flags & KExtraSpaceForSign) && (aDigBuf[0]!='-'))
+ numSpace--;
+
+ TInt nTriadSeps=(!doNotUseTriads && aFormat.iTriLen && (aExp>(TInt)aFormat.iTriLen))?(aExp-1)/3:0;
+ TInt maxDig=Min(aMaxSigFigs,afDigLimSize);
+ TInt maxSpace=numSpace-(aExp<=0?(2-aExp):((aExp<maxDig?1:aExp-maxDig)+nTriadSeps));
+ TInt nDig=Min(maxSpace,maxDig);
+ if (afDigLimSize>nDig && nDig<15 && nDig>=0 && (flags & KNeedsRounding) && round(aDigBuf.Ptr()+1,nDig,EFalse))
+ aExp++;
+
+ if (aDigBuf[0]=='0') // do zero first (numSpace>=0 so OK)
+ This->Append('0');
+ else
+ {
+ // check for overflow/underflow
+ if ((aExp+nTriadSeps)>numSpace)
+ return(KErrOverflow);
+ if (nDig<=0)
+ return(KErrUnderflow);
+
+ if ((flags&(TUint)KRealFormatTypesMask)!=(TUint)KRealFormatCalculator && aExp>aMaxSigFigs)
+ return(KErrOverflow);
+
+ TInt nDecPlcs=nDig-aExp;
+ while(nDecPlcs>0 && aDigBuf[nDig]=='0')
+ { // discard trailing zeros (already done in calculator)
+ nDecPlcs--;
+ nDig--;
+ }
+
+ if (aExp<=0) // hence number is of the form 0.NNNN
+ {
+ This->Append('0');
+ aExp=-aExp;
+ // if (nDecPlcs<=0) do nothing
+ if (nDecPlcs>0)
+ {
+ This->Append(aFormat.iPoint);
+ This->AppendFill('0',aExp);
+ for (TInt ii=1; ii<=nDig; ii++)
+ This->Append(TChar(aDigBuf[ii]));
+ }
+ }
+ else // aExp > 0 hence number is of the form NNNN.NNNN
+ {
+ for (TInt jj=1,ii=aExp; ii; ii--,jj++)
+ {
+ if (!doNotUseTriads && aFormat.iTriLen && aExp>(TInt)aFormat.iTriLen && !(ii%3) && ii!=aExp)
+ This->Append(aFormat.iTriad);
+ This->Append(TChar(jj<=nDig ? aDigBuf[jj] : '0'));
+ }
+ if (nDecPlcs>0)
+ {
+ This->Append(aFormat.iPoint);
+ for (TInt ii=aExp+1; ii<=nDig; ii++)
+ This->Append(TChar(aDigBuf[ii]));
+ }
+ }
+ }
+
+ return(KErrNone);
+ }
+
+LOCAL_C TInt doGeneral(TDes8 *This,TReal aSrc,TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp,
+ TInt aNumDecPlcs,const TInt aNumSpace,const TRealFormat &aFormat,TUint flags) __SOFTFP
+//
+// Convert the intermediate number represented in aDigBuf into either its fixed representation or
+// its exponential representation as appropriate and place the result in aTrg
+//
+// Annw, November 1996 - changed to allow space for sign in fixed mode, three-figure exponent.
+ {
+
+ TBool rounded=((flags & KNeedsRounding)==0);
+ TInt nDig=aDigBuf.Length()-1; // no of digits without sign
+ TInt type;
+
+ // Set up tempNumSpace to allow for leaving one space free for +ve nos in fixed format
+ TInt fixedNumSpace=aNumSpace;
+ if ((flags & KExtraSpaceForSign) && (aDigBuf[0]!='-'))
+ fixedNumSpace--;
+ if (fixedNumSpace<=0)
+ return(KErrGeneral);
+
+ FOREVER
+ {
+ // If aNumSpace < 5 cannot use exponential format, i.e. not enough space for XE+NN.
+ // If the exponent >= -3 (i.e. aExp >= -2), it is always more (or equally) efficient
+ // to use non-exponential format for negative exponents, i.e. XE-03 takes same no of
+ // spaces as 0.00X, and for positive exponents use fixed form as far as possible.
+
+ // for Java do not used fixed format for exponents >=7
+ // expMax=Min(fixedNumSpace,7)
+ // and replace "fixednumSpace" with "expMax" in next line
+
+ if (aNumSpace<5 || (aExp>=-2 && aExp<=fixedNumSpace))
+ {
+ type=KRealFormatFixed;
+
+ // if there is at least one digit before decimal point or no. is zero
+ if (aExp>0 || !aSrc)
+ {
+ if (nDig!=aExp)
+ // nDig is the number of digits which will be used
+ // a decimal point needed if exponent < digits in digbuf and numspace < nDig,
+ // so nDig is one less than otherwise
+ nDig=((nDig-aExp)>0 && fixedNumSpace>aExp)?Min(fixedNumSpace-1,nDig):Min(fixedNumSpace,nDig);
+ aNumDecPlcs=nDig-aExp;
+ }
+ else
+ {
+ // need space for "0." and to avoid white spaces
+ aNumDecPlcs=Min(fixedNumSpace-2,nDig-aExp);
+ // need space for "0.0...0" before any digits used
+ nDig=aNumDecPlcs+aExp;
+ if (nDig<0)
+ return KErrGeneral;
+ }
+ }
+ else
+ {
+ type=KRealFormatExponent; // Do NOT use significant figures
+ // Need to allow space for exponent
+ TInt tempNumSpace=aNumSpace-4; // 4 = E+NN
+ if ((flags & KAllowThreeDigitExp) && (Abs(aExp-1)>=100))
+ tempNumSpace--; // 5 = E+NNN
+ // if more than one digit available and enough digits to fill space, need to reduce
+ // number of digits to allow for '.'
+ if (((nDig=Min(tempNumSpace,nDig))>1) && nDig==tempNumSpace)
+ nDig--;
+ // in any case, aNumDecPlcs is one less that the number of digits,
+ // i.e. one digit before the point
+ aNumDecPlcs=nDig-1;
+ }
+ // if too many digbuf chars to fit then we need to round
+ // round() returns 1 if had to carry from msdigit
+ if ((afDigLimSize>nDig && !rounded) && ((rounded=round(aDigBuf.Ptr()+1,nDig,EFalse))!=0))
+ aExp++;
+ else
+ break;
+ }
+ while(aNumDecPlcs>0 && aDigBuf[nDig]=='0')
+ { // discard trailing zeros
+ aNumDecPlcs--;
+ nDig--;
+ }
+ flags=flags & ~KNeedsRounding;
+
+ if (type==KRealFormatExponent)
+ return(doExponent(This,aDigBuf,afDigLimSize,aExp,aNumDecPlcs,aNumSpace,(TText)aFormat.iPoint,flags));
+ return(doFixed(This,aDigBuf,afDigLimSize,aExp,aNumDecPlcs,aNumSpace,aFormat,flags));
+ }
+
+ LOCAL_C TInt doCalculator(TDes8 *This,TDes8 &aDigBuf,const TInt afDigLimSize,TInt aExp,
+ TInt aMaxSigFigs,const TInt aMaxSpace,const TRealFormat &aFormat, TUint flags)
+//
+// Added by AnnW, November 1996
+// Convert the intermediate number represented in aDigBuf into either its no exponent or its
+// exponential representation with a fixed number of significant figures and place the result
+// in aTrg
+//
+ {
+
+ TBool threeDigExp=((flags & KAllowThreeDigitExp)!=0);
+
+ // first check that enough space has been allowed for all the possible characters
+ // point + sign + all sig figs + exponent
+ if (aMaxSpace<(2+aMaxSigFigs+(threeDigExp?5:4)))
+ return(KErrGeneral);
+
+ // now discard trailing zeros
+ TInt nDig=afDigLimSize;
+ while(nDig>1 && aDigBuf[nDig]=='0')
+ {
+ nDig--;
+ }
+
+ TInt maxDig=Min(aMaxSigFigs,nDig); // max digs available
+ TBool rounded=((flags & KNeedsRounding)==0);
+ TInt type;
+ TBool useNoExp;
+
+ FOREVER
+ {
+ useNoExp=ETrue;
+ nDig=maxDig;
+
+ // use no exponent for all numbers which will not use > aMaxSigFigs digits
+ if (aExp>aMaxSigFigs || (aExp<=0 && (1-aExp+nDig)>aMaxSigFigs))
+ useNoExp=EFalse;
+
+ if (useNoExp)
+ type=KRealFormatNoExponent;
+ else
+ {
+ type=KRealFormatExponent;
+ threeDigExp=((Abs(aExp-1)>=KMinThreeDigitExponent && threeDigExp)!=0);
+ TInt temp=aMaxSpace-(threeDigExp?5:4);
+ nDig=Min(maxDig,temp-((temp>1 && maxDig>1)?1:0));
+ }
+
+ // if too many digbuf chars to fit then we need to round
+ // round() returns 1 if had to carry from msdigit
+ if ((afDigLimSize>nDig && !rounded) && ((rounded=round(aDigBuf.Ptr()+1,nDig,EFalse))!=0))
+ {
+ aExp++;
+ maxDig=1;
+ }
+ else
+ break;
+ }
+
+ TInt numSpace=aMaxSpace-(aDigBuf[0]=='-'?1:0);
+ flags=flags & ~KNeedsRounding;
+
+ if (type==KRealFormatExponent)
+ return(doExponent(This,aDigBuf,afDigLimSize,aExp,nDig,numSpace,(TText)aFormat.iPoint,flags));
+ else
+ {
+ flags|=KExtraSpaceForSign;
+ return(doNoExponent(This,aDigBuf,afDigLimSize,aExp,nDig,numSpace,aFormat,flags));
+ }
+ }
+
+TInt ProcessErrors(TDes8* aDes, TInt anError)
+ {
+ if (anError==KErrNone)
+ return aDes->Length();
+ if (anError==KErrUnderflow)
+ aDes->Append(TChar('0'));
+ if (anError==KErrOverflow)
+ aDes->Append(KLit8Inf());
+ if (anError==KErrArgument)
+ aDes->Append(KLit8Nan());
+ return anError;
+ }
+
+LOCAL_C TInt rtob(TDes8 *This,TReal aVal,const TRealFormat &aFormat) __SOFTFP
+//
+// Converts the real at aSrc. Returns the length of the converted string or an error number
+// if the buffer is too small, the number is out of range or there is insufficient KMaxPrecision
+// to represent the number.
+//
+// The conversion format is interpreted as follows:
+// KRealFormatFixed - ndec decimal places (including zero), negative values with a leading minus
+// sign, triad separators are available and a space may be left in front of positive numbers to
+// allow negative positve numbers to be given to the same precision.
+// KRealFormatExponent - exponent notation specifying either decimal places or significant
+// figures in the mantissa and a signed exponent given to a maximum of two or three digits,
+// and no triad separator.
+// KTRealFormatGeneral - converts either as fixed or exponent to make best use of the available
+// width. The number of decimal spaces is chosen automatically as a function of width
+// (ndec is ignored), no triad.
+// KRealFormatNoExponent - as KRealForamtFixed, but specifying maximum significant figures and
+// not introducing trailing zeros.
+// KRealFormatCalculator - as KRealFormatGeneral, but behaves as a conventional calculator. A
+// maximum number of significant figures is specified and the number is displayed without an
+// exponent whenever possible, with no trailing zeros and no triads.
+//
+// If an error value other than KErrGeneral is returned the real is converted to some string:
+// "+/-Inf" if the error is KErrOverflow, "NaN" if the error is KErrArgument or "0" if it is
+// KErrUnderflow.
+//
+ {
+ if (aFormat.iWidth>This->MaxLength())
+ return(KErrGeneral);
+ TBuf8<0x20> digbuf;
+ TInt exp=0;
+ TInt numspace=aFormat.iWidth;
+ TInt maxspace=numspace;
+ TInt prec = KMaxPrecision;
+ if (aFormat.iType & KRealInjectiveLimit)
+ prec = KIEEEDoubleInjectivePrecision;
+ else if (aFormat.iType & KGeneralLimit)
+ prec = KPrecisionLimit;
+ TInt ret=fDigLim(digbuf,aVal,exp,prec);
+ digbuf.ZeroTerminate();
+ TInt type, flags;
+
+ if (digbuf[0]=='0')
+ exp=0;
+ else
+ {
+ if (digbuf[0]=='-' && ret!=KErrArgument) // NaN has no sign
+ {
+ This->Append('-');
+ numspace--;
+ }
+ if (ret<0)
+ return ProcessErrors(This, ret);
+ else
+ ret--;
+ }
+
+ //Added by AnnW
+ if (numspace<=0)
+ return(KErrGeneral);
+ if (aFormat.iType & ~KRealFormatTypesMask & ~KRealFormatTypeFlagsMask)
+ return(KErrGeneral);
+ type=aFormat.iType & KRealFormatTypesMask;
+ flags=((aFormat.iType & KRealFormatTypeFlagsMask)| KNeedsRounding);
+ // end of added
+
+ switch(type)
+ {
+ case KRealFormatFixed:
+ flags=flags & ~KUseSigFigs; // if flag is NOT set and iTriLen!=0, uses triads
+ ret=doFixed(This,digbuf,ret,exp,aFormat.iPlaces,numspace,aFormat,flags);
+ break;
+ case KRealFormatExponent:
+ ret=doExponent(This,digbuf,ret,exp,aFormat.iPlaces,numspace,(TText)aFormat.iPoint,flags);
+ break;
+ case KRealFormatGeneral:
+ flags=(flags & ~KUseSigFigs) | KDoNotUseTriads;
+ ret=doGeneral(This,aVal,digbuf,ret,exp,aFormat.iPlaces,numspace,aFormat,flags);
+ break;
+ case KRealFormatNoExponent:
+ flags=flags | KUseSigFigs; // if flag is NOT set and iTriLen!=0, uses triads
+ ret=doNoExponent(This,digbuf,ret,exp,aFormat.iPlaces,numspace,aFormat,flags);
+ break;
+ case KRealFormatCalculator:
+ flags=(flags | KUseSigFigs) | KDoNotUseTriads | KRealFormatCalculator;
+ ret=doCalculator(This,digbuf,ret,exp,aFormat.iPlaces,maxspace,aFormat,flags);
+ break;
+ default:
+ return(KErrGeneral);
+ }
+ return ProcessErrors(This, ret);
+ }
+
+
+
+
+EXPORT_C TRealFormat::TRealFormat()
+/**
+Default constructor.
+
+The public data members of the constructed object are assigned
+the following values:
+
+TRealFormat::iType - set to KRealFormatGeneral
+
+TRealFormat::iWidth - set to KDefaultRealWidth
+
+TRealFormat::iPlaces - set to 0
+
+TRealFormat::iPoint - set to the decimal separator character defined in
+ a TLocale object and returned by the DecimalSeparator()
+ member function of that class.
+
+TRealFormat::iTriad - set to the character used to delimit groups of three
+ digits in the integer portion of a number; the character
+ is defined in a TLocale object and returned by the
+ ThousandsSeparator() member function of that class.
+
+TRealFormat::iTriLen - set to 1
+
+@see TLocale::DecimalSeparator
+@see TLocale::ThousandsSeparator
+*/
+ {
+
+ iType=KRealFormatGeneral;
+ iWidth=KDefaultRealWidth;
+ iPlaces=0;
+ TLocale locale;
+ iPoint=locale.DecimalSeparator();
+ iTriad=locale.ThousandsSeparator();
+ iTriLen=1;
+ }
+
+
+
+
+EXPORT_C TRealFormat::TRealFormat(TInt aWidth)
+/**
+Constructs the object taking the width of the character representation.
+
+The remaining public data members of the constructed object are assigned
+the following values:
+
+TRealFormat::iType - set to KRealFormatGeneral
+
+TRealFormat::iWidth - set to the aWidth argument
+
+TRealFormat::iPlaces - set to 0
+
+TRealFormat::iPoint - set to the decimal separator character defined in
+ a TLocale object and returned by the DecimalSeparator()
+ member function of that class.
+
+TRealFormat::iTriad - set to the character used to delimit groups of three
+ digits in the integer portion of a number; the character
+ is defined in a TLocale object and returned by the
+ ThousandsSeparator() member function of that class.
+
+TRealFormat::iTriLen - set to 1
+
+@param aWidth The width of the character representation of the real number.
+
+@see TLocale::DecimalSeparator
+@see TLocale::ThousandsSeparator
+*/
+ {
+
+ iType=KRealFormatGeneral;
+ iWidth=aWidth;
+ iPlaces=0;
+ TLocale locale;
+ iPoint=locale.DecimalSeparator();
+ iTriad=locale.ThousandsSeparator();
+ iTriLen=1;
+ }
+
+
+
+
+EXPORT_C TRealFormat::TRealFormat(TInt aWidth,TInt aDecimals)
+/**
+Constructs the object taking the width of the character representation
+and a value which is interpreted as the number of digits to follow
+the decimal point.
+
+The remaining public data members of the constructed object are assigned
+the following values:
+
+TRealFormat::iType - set to KRealFormatFixed
+
+TRealFormat::iWidth - set to the aWidth argument
+
+TRealFormat::iPlaces - set to the aDecimals argument
+
+TRealFormat::iPoint - set to the decimal separator character defined in
+ a TLocale object and returned by the DecimalSeparator()
+ member function of that class.
+
+TRealFormat::iTriad - set to the character used to delimit groups of three
+ digits in the integer portion of a number; the character
+ is defined in a TLocale object and returned by the
+ ThousandsSeparator() member function of that class.
+
+TRealFormat::iTriLen - set to 1
+
+Note that if the iType data member is changed after construction, aDecimalPlaces
+may be interpreted as the number of significant digits. For more information,
+see KRealFormatFixed and the other format types, and KExtraSpaceForSign and the
+other format flags.
+
+@param aWidth The width of the character representation of the real number.
+@param aDecimals The number of digits to follow the decimal point.
+
+@see TLocale::DecimalSeparator()
+@see TLocale::ThousandsSeparator()
+@see KRealFormatFixed
+@see KExtraSpaceForSign
+*/
+ {
+
+ iType=KRealFormatFixed;
+ iWidth=aWidth;
+ iPlaces=aDecimals;
+ TLocale locale;
+ iPoint=locale.DecimalSeparator();
+ iTriad=locale.ThousandsSeparator();
+ iTriLen=1;
+ }
+
+
+
+
+EXPORT_C TInt Math::Round(TReal &aTrg,const TReal &aSrc,TInt aDecimalPlaces)
+/**
+Rounds to a specified number of decimal places.
+
+The function rounds a number to a given number, n, of decimal places.
+Rounding may be thought of as multiplying the number by 10 to the power of n,
+rounding to the nearest integer, and then dividing the result by 10 to
+the power of n and returning that as the answer.
+
+In the process of rounding, numbers ending with .5 are rounded away from zero,
+so that 1.5 becomes 2, 2.5 becomes 3, -1.5 becomes -2, etc.
+
+@param aTrg A reference containing the result.
+@param aSrc The number to be rounded.
+@param aDecimalPlaces The number of decimal places to round to: must be
+ zero or positive.
+
+@return KErrNone if successful, otherwise another of the system-wide error codes.
+*/
+ {
+
+ if (aSrc==0.0)
+ {
+ aTrg=aSrc;
+ return(KErrNone);
+ }
+ TInt ret,exp;
+ TBuf8<0x20> rbuf;
+ if ((ret=fDigLim(rbuf,aSrc,exp,KIEEEDoubleInjectivePrecision))<0)
+ return(ret);
+ if ((exp+aDecimalPlaces)<0)
+ { // Number too small to be rounded
+ aTrg=0;
+ return(KErrNone);
+ }
+ if ((ret-2)<(exp+aDecimalPlaces)) //ret is the string length, including prefixed +/-
+ { // Rounding will have no effect
+ aTrg=aSrc;
+ return(KErrNone);
+ }
+ if ((ret=round(rbuf.Ptr()+1,exp+aDecimalPlaces,EFalse))!=KErrNone)
+ exp++;
+ rbuf.Insert(1,TPtrC8((TText8*)".",1));
+ rbuf.SetLength(exp+aDecimalPlaces+2);
+ if (!(exp+aDecimalPlaces))
+ rbuf.Append('0');
+// rbuf.AppendFormat(TPtrC8((TText8*)"%c%d",4),'E',exp);
+ rbuf.Append(TChar('E'));
+ rbuf.AppendNum(exp);
+ return(((TLex8)rbuf).Val(aTrg,(TChar)'.'));
+ }
+
+EXPORT_C TInt TDes8::Num(TReal aVal,const TRealFormat &aFormat) __SOFTFP
+/**
+Converts the specified floating point number into a character representation
+and copies the conversion into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+The character representation of the real number is dictated by the specified
+format.
+
+Note that the function leaves if the iType data member of the specified
+TRealFormat object has both an invalid character representation format
+(i.e. the format type) and invalid format flags.
+
+@param aVal The floating point number to be converted.
+@param aFormat The format of the conversion.
+
+@return If the conversion is successful, the length of this descriptor. If
+ the conversion fails, a negative value indicating the cause of failure.
+ In addition, extra information on the cause of the failure may be
+ appended onto this descriptor. The possible values and their meaning
+ are:
+
+ 1.KErrArgument - the supplied floating point number is not a valid
+ number. The three characters NaN are appended to this descriptor.
+
+ 2.KErrOverflow - the number is too large to represent.
+ 2.1 For positive overflow, the three characters Inf are appended
+ to this descriptor.
+ 2.2 For negative overflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 3.KErrUnderflow - the number is too small to represent.
+ 3.1 For positive underflow, the three characters Inf are appended
+ to this descriptor.
+ 3.2 For negative underflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 4.KErrGeneral - the conversion cannot be completed. There are a
+ number of possible reasons for this, but the two most common
+ are:
+ 4.1 the maximum number of characters necessary to represent the number,
+ as defined in the TRealFormat object, is greater than the maximum
+ length of this descriptor
+ 4.2 the character representation format (i.e. the format type), as
+ defined in the TRealFormat object is not recognised.
+
+@see TRealFormat::iType
+*/
+ {
+
+ Zero();
+ return(rtob(this,aVal,aFormat));
+ }
+
+EXPORT_C TInt TDes8::AppendNum(TReal aVal,const TRealFormat &aFormat) __SOFTFP
+/**
+Converts the specified floating point number into a character representation
+and appends the conversion onto the end of this descriptor's data.
+
+The length of this descriptor is incremented to reflect the new content.
+
+The character representation of the real number is dictated by the specified
+format.
+
+@param aVal The floating point number to be converted.
+@param aFormat The format of the conversion.
+
+@return If the conversion is successful, the length of this descriptor. If
+ the conversion fails, a negative value indicating the cause of failure.
+ In addition, extra information on the cause of the failure may be
+ appended onto this descriptor. The possible values and their meaning
+ are:
+
+ 1.KErrArgument - the supplied floating point number is not a valid
+ number. The three characters NaN are appended to this descriptor.
+
+ 2.KErrOverflow - the number is too large to represent.
+ 2.1 For positive overflow, the three characters Inf are appended
+ to this descriptor.
+ 2.2 For negative overflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 3.KErrUnderflow - the number is too small to represent.
+ 3.1 For positive underflow, the three characters Inf are appended
+ to this descriptor.
+ 3.2 For negative underflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 4.KErrGeneral - the conversion cannot be completed. There are a
+ number of possible reasons for this, but the two most common
+ are:
+ 4.1 the maximum number of characters necessary to represent the number,
+ as defined in the TRealFormat object, is greater than the maximum
+ length of this descriptor
+ 4.2 the character representation format (i.e. the format type), as
+ defined in the TRealFormat object is not recognised
+*/
+ {
+
+ return(rtob(this,aVal,aFormat));
+ }
+
+EXPORT_C TInt TDes16::Num(TReal aVal,const TRealFormat &aFormat) __SOFTFP
+/**
+Converts the specified floating point number into a character representation
+and copies the conversion into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+The character representation of the real number is dictated by the specified
+format.
+
+Note that the function leaves if the iType data member of the specified
+TRealFormat object has both an invalid character representation format
+(i.e. the format type) and invalid format flags.
+
+@param aVal The floating point number to be converted.
+@param aFormat The format of the conversion.
+
+@return If the conversion is successful, the length of this descriptor. If
+ the conversion fails, a negative value indicating the cause of failure.
+ In addition, extra information on the cause of the failure may be
+ appended onto this descriptor. The possible values and their meaning
+ are:
+
+ 1.KErrArgument - the supplied floating point number is not a valid
+ number. The three characters NaN are appended to this descriptor.
+
+ 2.KErrOverflow - the number is too large to represent.
+ 2.1 For positive overflow, the three characters Inf are appended
+ to this descriptor.
+ 2.2 For negative overflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 3.KErrUnderflow - the number is too small to represent.
+ 3.1 For positive underflow, the three characters Inf are appended
+ to this descriptor.
+ 3.2 For negative underflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 4.KErrGeneral - the conversion cannot be completed. There are a
+ number of possible reasons for this, but the two most common
+ are:
+ 4.1 the maximum number of characters necessary to represent the number,
+ as defined in the TRealFormat object, is greater than the maximum
+ length of this descriptor
+ 4.2 the character representation format (i.e. the format type), as
+ defined in the TRealFormat object is not recognised.
+
+@see TRealFormat::iType
+*/
+ {
+
+ Zero();
+ return (AppendNum(aVal,aFormat));
+ }
+
+EXPORT_C TInt TDes16::AppendNum(TReal aVal,const TRealFormat &aFormat) __SOFTFP
+/**
+Converts the specified floating point number into a character representation
+and appends the conversion onto the end of this descriptor's data.
+
+The length of this descriptor is incremented to reflect the new content.
+
+The character representation of the real number is dictated by the specified
+format.
+
+@param aVal The floating point number to be converted.
+@param aFormat The format of the conversion.
+
+@return If the conversion is successful, the length of this descriptor. If
+ the conversion fails, a negative value indicating the cause of failure.
+ In addition, extra information on the cause of the failure may be
+ appended onto this descriptor. The possible values and their meaning
+ are:
+
+ 1.KErrArgument - the supplied floating point number is not a valid
+ number. The three characters NaN are appended to this descriptor.
+
+ 2.KErrOverflow - the number is too large to represent.
+ 2.1 For positive overflow, the three characters Inf are appended
+ to this descriptor.
+ 2.2 For negative overflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 3.KErrUnderflow - the number is too small to represent.
+ 3.1 For positive underflow, the three characters Inf are appended
+ to this descriptor.
+ 3.2 For negative underflow, the four characters -Inf are appended
+ to this descriptor.
+
+ 4.KErrGeneral - the conversion cannot be completed. There are a
+ number of possible reasons for this, but the two most common
+ are:
+ 4.1 the maximum number of characters necessary to represent the number,
+ as defined in the TRealFormat object, is greater than the maximum
+ length of this descriptor
+ 4.2 the character representation format (i.e. the format type), as
+ defined in the TRealFormat object is not recognised
+*/
+ {
+
+ HBufC8 *temp=HBufC8::New(MaxLength());
+ if (temp==NULL)
+ return(KErrNoMemory);
+ TPtr8 p(temp->Des());
+ TInt ret=rtob(&p,aVal,aFormat);
+ const TText8 *pTemp=temp->Ptr();
+ for (TInt ii=temp->Length();ii>0;ii--)
+ Append(*pTemp++);
+ if (ret>0)
+ ret=Length();
+ User::Free(temp);
+ return (ret);
+ }