kernel/eka/euser/maths/um_rtod.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 	}