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