os/kernelhwsrv/kernel/eka/euser/maths/um_pow10.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\euser\maths\um_pow10.cpp
    15 // Return a power of 10 as a TReal
    16 // 
    17 //
    18 
    19 #include "um_std.h"
    20 
    21 #if defined(__USE_VFP_MATH) && !defined(__CPU_HAS_VFP)
    22 #error	__USE_VFP_MATH was defined but not __CPU_HAS_VFP - impossible combination, check variant.mmh 
    23 #endif
    24 
    25 
    26 // Tables of powers of 10
    27 LOCAL_D const TUint32 PositivePowersOfTen[] =
    28 	{
    29 // Positive powers 1-31
    30 	0x00000000,0xA0000000,0x80020000,
    31 	0x00000000,0xC8000000,0x80050000,
    32 	0x00000000,0xFA000000,0x80080000,
    33 	0x00000000,0x9C400000,0x800C0000,
    34 	0x00000000,0xC3500000,0x800F0000,
    35 	0x00000000,0xF4240000,0x80120000,
    36 	0x00000000,0x98968000,0x80160000,
    37 	0x00000000,0xBEBC2000,0x80190000,
    38 	0x00000000,0xEE6B2800,0x801C0000,
    39 	0x00000000,0x9502F900,0x80200000,
    40 	0x00000000,0xBA43B740,0x80230000,
    41 	0x00000000,0xE8D4A510,0x80260000,
    42 	0x00000000,0x9184E72A,0x802A0000,
    43 	0x80000000,0xB5E620F4,0x802D0000,
    44 	0xA0000000,0xE35FA931,0x80300000,
    45 	0x04000000,0x8E1BC9BF,0x80340000,
    46 	0xC5000000,0xB1A2BC2E,0x80370000,
    47 	0x76400000,0xDE0B6B3A,0x803A0000,
    48 	0x89E80000,0x8AC72304,0x803E0000,
    49 	0xAC620000,0xAD78EBC5,0x80410000,
    50 	0x177A8000,0xD8D726B7,0x80440000,
    51 	0x6EAC9000,0x87867832,0x80480000,
    52 	0x0A57B400,0xA968163F,0x804B0000,
    53 	0xCCEDA100,0xD3C21BCE,0x804E0000,
    54 	0x401484A0,0x84595161,0x80520000,
    55 	0x9019A5C8,0xA56FA5B9,0x80550000,
    56 	0xF4200F3A,0xCECB8F27,0x80580000,
    57 	0xF8940984,0x813F3978,0x805C0000,
    58 	0x36B90BE5,0xA18F07D7,0x805F0000,
    59 	0x04674EDF,0xC9F2C9CD,0x80620000,
    60 	0x45812296,0xFC6F7C40,0x80650000,
    61 
    62 // Positive powers 32-31*32 in steps of 32
    63 	0x2B70B59E,0x9DC5ADA8,0x80690000,
    64 	0xFFCFA6D5,0xC2781F49,0x80D30000,
    65 	0xC59B14A3,0xEFB3AB16,0x813D0000,
    66 	0x80E98CE0,0x93BA47C9,0x81A80000,
    67 	0x7FE617AA,0xB616A12B,0x82120000,
    68 	0x3927556B,0xE070F78D,0x827C0000,
    69 	0xE33CC930,0x8A5296FF,0x82E70000,
    70 	0x9DF9DE8E,0xAA7EEBFB,0x83510000,
    71 	0x5C6A2F8C,0xD226FC19,0x83BB0000,
    72 	0xF2CCE376,0x81842F29,0x84260000,
    73 	0xDB900AD2,0x9FA42700,0x84900000,
    74 	0xAEF8AA17,0xC4C5E310,0x84FA0000,
    75 	0xE9B09C59,0xF28A9C07,0x85640000,
    76 	0xEBF7F3D4,0x957A4AE1,0x85CF0000,
    77 	0x0795A262,0xB83ED8DC,0x86390000,
    78 	0xA60E91C7,0xE319A0AE,0x86A30000,
    79 	0x432D7BC3,0x8BF61451,0x870E0000,
    80 	0x6B6795FD,0xAC83FB89,0x87780000,
    81 	0xB8FA79B0,0xD4A44FB4,0x87E20000,
    82 	0xE54A9D1D,0x830CF791,0x884D0000,
    83 	0xADE24964,0xA1884B69,0x88B70000,
    84 	0x1F8F01CC,0xC71AA36A,0x89210000,
    85 	0x437028F3,0xF56A298F,0x898B0000,
    86 	0xCD00A68C,0x973F9CA8,0x89F60000,
    87 	0xD7CC9ECD,0xBA6D9B40,0x8A600000,
    88 	0x8D737F0E,0xE5CA5A0B,0x8ACA0000,
    89 	0x1346BDA5,0x8D9E89D1,0x8B350000,
    90 	0xE3D5DBEA,0xAE8F2B2C,0x8B9F0000,
    91 	0x5A0C1B30,0xD7293020,0x8C090000,
    92 	0x0D2ECFD2,0x849A672A,0x8C740000,
    93 	0x41FA93DE,0xA3722C13,0x8CDE0000,
    94 
    95 // Positive powers 1024-8*1024 in steps of 1024
    96 	0x81750C17,0xC9767586,0x8D480000,
    97 	0xC53D5DE5,0x9E8B3B5D,0x9A920000,
    98 	0xD88B5A8B,0xF9895D25,0xA7DB0000,
    99 	0x8A20979B,0xC4605202,0xB5250000,
   100 	0xFED3AB23,0x9A8A7EF0,0xC26F0000,
   101 	0x73A56037,0xF33C80E8,0xCFB80000,
   102 	0x61889066,0xBF6B0EC4,0xDD020000,
   103 	0x7FAF211A,0x96A3A1D1,0xEA4C0000
   104 	};
   105 
   106 LOCAL_D const TUint32 NegativePowersOfTen[] =
   107 	{
   108 // Negative powers 1-31
   109 	0xCCCCCCCD,0xCCCCCCCC,0x7FFB0000,
   110 	0x70A3D70A,0xA3D70A3D,0x7FF80000,
   111 	0x8D4FDF3B,0x83126E97,0x7FF50000,
   112 	0xE219652C,0xD1B71758,0x7FF10000,
   113 	0x1B478423,0xA7C5AC47,0x7FEE0000,
   114 	0xAF6C69B6,0x8637BD05,0x7FEB0000,
   115 	0xE57A42BC,0xD6BF94D5,0x7FE70000,
   116 	0x8461CEFD,0xABCC7711,0x7FE40000,
   117 	0x36B4A597,0x89705F41,0x7FE10000,
   118 	0xBDEDD5BF,0xDBE6FECE,0x7FDD0000,
   119 	0xCB24AAFF,0xAFEBFF0B,0x7FDA0000,
   120 	0x6F5088CC,0x8CBCCC09,0x7FD70000,
   121 	0x4BB40E13,0xE12E1342,0x7FD30000,
   122 	0x095CD80F,0xB424DC35,0x7FD00000,
   123 	0x3AB0ACD9,0x901D7CF7,0x7FCD0000,
   124 	0xC44DE15B,0xE69594BE,0x7FC90000,
   125 	0x36A4B449,0xB877AA32,0x7FC60000,
   126 	0x921D5D07,0x9392EE8E,0x7FC30000,
   127 	0xB69561A5,0xEC1E4A7D,0x7FBF0000,
   128 	0x92111AEB,0xBCE50864,0x7FBC0000,
   129 	0x74DA7BEF,0x971DA050,0x7FB90000,
   130 	0xBAF72CB1,0xF1C90080,0x7FB50000,
   131 	0x95928A27,0xC16D9A00,0x7FB20000,
   132 	0x44753B53,0x9ABE14CD,0x7FAF0000,
   133 	0xD3EEC551,0xF79687AE,0x7FAB0000,
   134 	0x76589DDB,0xC6120625,0x7FA80000,
   135 	0x91E07E48,0x9E74D1B7,0x7FA50000,
   136 	0x8300CA0E,0xFD87B5F2,0x7FA10000,
   137 	0x359A3B3E,0xCAD2F7F5,0x7F9E0000,
   138 	0x5E14FC32,0xA2425FF7,0x7F9B0000,
   139 	0x4B43FCF5,0x81CEB32C,0x7F980000,
   140 
   141 // Negative powers 32-31*32 in steps of 32
   142 	0x453994BA,0xCFB11EAD,0x7F940000,
   143 	0xA539E9A5,0xA87FEA27,0x7F2A0000,
   144 	0xFD75539B,0x88B402F7,0x7EC00000,
   145 	0x64BCE4A1,0xDDD0467C,0x7E550000,
   146 	0xDB73A093,0xB3F4E093,0x7DEB0000,
   147 	0x5423CC06,0x91FF8377,0x7D810000,
   148 	0x4A314EBE,0xECE53CEC,0x7D160000,
   149 	0x637A193A,0xC0314325,0x7CAC0000,
   150 	0x836AC577,0x9BECCE62,0x7C420000,
   151 	0x478238D1,0xFD00B897,0x7BD70000,
   152 	0x46F34F7D,0xCD42A113,0x7B6D0000,
   153 	0xB11B0858,0xA686E3E8,0x7B030000,
   154 	0x3FFC68A6,0x871A4981,0x7A990000,
   155 	0xB6074245,0xDB377599,0x7A2E0000,
   156 	0x79007736,0xB1D983B4,0x79C40000,
   157 	0xDB23D21C,0x9049EE32,0x795A0000,
   158 	0x467F9466,0xEA1F3806,0x78EF0000,
   159 	0xEE5092C7,0xBDF139F0,0x78850000,
   160 	0xB4730DD0,0x9A197865,0x781B0000,
   161 	0x8871347D,0xFA0A6CDB,0x77B00000,
   162 	0x3C8736FC,0xCADB6D31,0x77460000,
   163 	0x52EB8375,0xA493C750,0x76DC0000,
   164 	0x774FB85E,0x85855C0F,0x76720000,
   165 	0x505DE96B,0xD8A66D4A,0x76070000,
   166 	0xCB39A7B1,0xAFC47766,0x759D0000,
   167 	0xA9B05AC8,0x8E997872,0x75330000,
   168 	0xFDC06462,0xE761832E,0x74C80000,
   169 	0xBB827F2D,0xBBB7EF38,0x745E0000,
   170 	0xE1F045DD,0x984B9B19,0x73F40000,
   171 	0x3613F568,0xF71D01E0,0x73890000,
   172 	0x3F64789E,0xC87B6D2F,0x731F0000,
   173 
   174 // Negative powers 1024-8*1024 in steps of 1024
   175 	0xDA57C0BE,0xA2A682A5,0x72B50000,
   176 	0x34362DE4,0xCEAE534F,0x656B0000,
   177 	0x91575A88,0x8350BF3C,0x58220000,
   178 	0xD2CE9FDE,0xA6DD04C8,0x4AD80000,
   179 	0x0DA5D8E8,0xD408CB01,0x3D8E0000,
   180 	0x22EB58E9,0x86B77A60,0x30450000,
   181 	0x4779611E,0xAB2F7655,0x22FB0000,
   182 	0x686DA869,0xD986C20B,0x15B10000
   183 	};
   184 
   185 TInt Math::MultPow10X(TRealX& aTrg, TInt aPower)
   186 	{
   187 	if (aTrg.IsZero())
   188 		return KErrNone;
   189 	if (!aTrg.IsFinite())
   190 		{
   191 		if (aTrg.IsNaN())
   192 			return KErrArgument;
   193 		return KErrOverflow;
   194 		}
   195 	if (aPower==0)
   196 		return KErrNone;
   197 	// smallest non-zero TRealX is 2^-32766=2.83E-9864
   198 	// largest TRealX is 2^32768=1.42E+9864
   199 	// Therefore aPower>=19728 guarantees an overflow
   200 	// and aPower<=-19728 guarantees an underflow
   201 	if (aPower>=19728)
   202 		{
   203 		aTrg.SetInfinite(aTrg.iSign);
   204 		return KErrOverflow;
   205 		}
   206 	if (aPower<=-19728)
   207 		{
   208 		aTrg.SetZero(aTrg.iSign);
   209 		return KErrUnderflow;
   210 		}
   211 	const TRealX* powTab;
   212 	if (aPower>0)
   213 		powTab=(const TRealX*)PositivePowersOfTen;
   214 	else
   215 		{
   216 		aPower=-aPower;
   217 		powTab=(const TRealX*)NegativePowersOfTen;
   218 		}
   219 	TInt r=KErrNone;
   220 	while(aPower>=8192)
   221 		{
   222 		aPower-=8192;
   223 		r=aTrg.MultEq(powTab[31+31+7]);
   224 		if (r!=KErrNone)
   225 			return r;
   226 		}
   227 	TInt bottom5=aPower & 0x1f;
   228 	TInt middle5=(aPower>>5)&0x1f;
   229 	TInt top3=(aPower>>10);
   230 	if (top3)
   231 		r=aTrg.MultEq(powTab[31+31+top3-1]);
   232 	if (r==KErrNone && middle5)
   233 		r=aTrg.MultEq(powTab[31+middle5-1]);
   234 	if (r==KErrNone && bottom5)
   235 		r=aTrg.MultEq(powTab[bottom5-1]);
   236 	return r;
   237 	}
   238 
   239 
   240 
   241 
   242 EXPORT_C TInt Math::Pow10(TReal &aTrg,const TInt aExp)
   243 /**
   244 Calculates the value of 10 to the power of x.
   245 
   246 @param aTrg A reference containing the result. 
   247 @param aExp The power to which 10 is to be raised.
   248 
   249 @return KErrNone if successful, otherwise another of
   250         the system-wide error codes.
   251 */
   252 //
   253 // Write the binary floating point representation of a power of 10 to aSrc
   254 // Returns KErrNone if OK or a negative error number otherwise.
   255 //
   256 	{
   257 #ifndef __USE_VFP_MATH
   258 	TRealX x=1;
   259 	TInt r=Math::MultPow10X(x,aExp);
   260 	TInt s=x.GetTReal(aTrg);
   261 	return (r==KErrNone)?s:r;
   262 #else // __USE_VFP_MATH
   263 	return Math::Pow(aTrg,10,aExp);
   264 #endif
   265 	}