os/kernelhwsrv/kernel/eka/euser/maths/um_int.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_int.cpp
    15 // Writes the integer part aTrg to aSrc (aSrc is either TReal,TInt16 orTInt32)
    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 #ifndef __USE_VFP_MATH
    26 
    27 #ifndef __REALS_MACHINE_CODED__
    28 EXPORT_C TInt Math::Int(TReal &aTrg,const TReal &aSrc)
    29 /**
    30 Calculates the integer part of a number.
    31 
    32 The integer part is that before a decimal point.
    33 Truncation is toward zero, so that
    34 int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1.
    35 
    36 
    37 @param aTrg A reference containing the result. 
    38 @param aSrc The number whose integer part is required. 
    39 
    40 @return KErrNone if successful, otherwise another of
    41         the system-wide error codes. 
    42 */
    43 	{
    44 	TRealX f;
    45 	TInt ret=f.Set(aSrc);
    46 	if (ret!=KErrNone)
    47 		{
    48 		aTrg=aSrc;
    49 		return(ret);
    50 		}
    51 	TInt intbits=f.iExp-0x7FFE;	// number of integer bits in mantissa
    52 	if (intbits<=0)
    53 		{
    54 		SetZero(aTrg,f.iSign&1); // no integer part
    55 		return(KErrNone);
    56 		}
    57 	if (intbits>=KMantissaBits)
    58 		{
    59 		aTrg=aSrc; // fractional part is outside range of significance
    60 		return(KErrNone);
    61 		}
    62 
    63 	TUint64 mask = ~(UI64LIT(0));
    64 	mask <<= (64 - intbits);
    65 
    66 	f.iMantHi &= static_cast<TUint32>(mask >> 32);
    67 	f.iMantLo &= static_cast<TUint32>(mask);
    68 
    69 	f.GetTReal(aTrg);
    70 	return(KErrNone);
    71 	}
    72 
    73 
    74 
    75 
    76 EXPORT_C TInt Math::Int(TInt16 &aTrg,const TReal &aSrc)
    77 /**
    78 Calculates the integer part of a number.
    79 
    80 The integer part is that before a decimal point.
    81 Truncation is toward zero, so that
    82 int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1.
    83 
    84 This function is suitable when the result is known to be small enough
    85 for a 16-bit signed integer.
    86 
    87 @param aTrg A reference containing the result. 
    88 @param aSrc The number whose integer part is required.
    89 
    90 @return KErrNone if successful, otherwise another of
    91         the system-wide error codes.
    92 */
    93 //
    94 // If the integer part of aSrc is in the range -32768 to +32767
    95 // inclusive, write the integer part to the TInt16 at aTrg
    96 // Negative numbers are rounded towards zero.
    97 // If an overflow or underflow occurs, aTrg is set to the max/min value
    98 //
    99 	{
   100 	TRealX f;
   101 	TInt ret=f.Set(aSrc);
   102 
   103 	if (ret==KErrArgument)
   104 		{
   105 		aTrg=0;
   106 		return(ret);
   107 		}
   108 
   109 	TInt intbits=f.iExp-0x7FFE;	// number of integer bits in mantissa
   110 
   111 	if (intbits<=0)
   112 		{
   113 		aTrg=0;
   114 		return(KErrNone);
   115 		}
   116 
   117 	if (intbits>16)
   118 		{
   119 		aTrg=(TInt16)((f.iSign&1) ? KMinTInt16 : KMaxTInt16);
   120 		return((f.iSign&1) ? KErrUnderflow : KErrOverflow);
   121 		}
   122 
   123 	TUint val = f.iMantHi >> (32 - intbits);
   124 
   125 	if ((f.iSign&1)==0 && val>(TUint)KMaxTInt16)
   126 		{
   127 		aTrg=TInt16(KMaxTInt16);
   128 		return(KErrOverflow);
   129 		}
   130 
   131 	if ((f.iSign&1) && val>(TUint)(KMaxTInt16+1))
   132 		{
   133 		aTrg=TInt16(KMinTInt16);
   134 		return(KErrUnderflow);
   135 		}
   136 
   137 	aTrg = (f.iSign&1) ? (TInt16)(-(TInt)val) : (TInt16)val;
   138 
   139 	return(KErrNone);
   140 	} 
   141 
   142 
   143 
   144 
   145 EXPORT_C TInt Math::Int(TInt32 &aTrg,const TReal &aSrc)
   146 /**
   147 Calculates the integer part of a number.
   148 
   149 The integer part is that before a decimal point.
   150 Truncation is toward zero, so that
   151 int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1.
   152 
   153 This function is suitable when the result is known to be small enough
   154 for a 32-bit signed integer.
   155 
   156 @param aTrg A reference containing the result. 
   157 @param aSrc The number whose integer part is required.
   158 
   159 @return KErrNone if successful, otherwise another of
   160         the system-wide error codes.
   161 */
   162 //													 
   163 // If the integer part of the float is in the range -2147483648 to +2147483647
   164 // inclusive, write the integer part to the TInt32 at aTrg
   165 // Negative numbers are rounded towards zero.
   166 // If an overflow or underflow occurs, aTrg is set to the max/min value
   167 //
   168 	{
   169 	TRealX f;
   170 	TInt ret=f.Set(aSrc);
   171 
   172 	if (ret==KErrArgument)
   173 		{
   174 		aTrg=0;
   175 		return(ret);
   176 		}
   177 
   178 	TInt intbits=f.iExp-0x7FFE;	// number of integer bits in mantissa
   179 
   180 	if (intbits<=0)
   181 		{
   182 		aTrg=0;
   183 		return(KErrNone);
   184 		}
   185 
   186 	if (intbits>32)
   187 		{
   188 		aTrg=((f.iSign&1) ? KMinTInt32 : KMaxTInt32);
   189 		return((f.iSign&1) ? KErrUnderflow : KErrOverflow);
   190 		}
   191 
   192 	TUint val = f.iMantHi >> (32 - intbits);
   193 
   194 	if ((f.iSign&1)==0 && val>(TUint)KMaxTInt32)
   195 		{
   196 		aTrg=KMaxTInt32;
   197 		return(KErrOverflow);
   198 		}
   199 
   200 	if ((f.iSign&1) && val>((TUint)KMaxTInt32+1))
   201 		{
   202 		aTrg=KMinTInt32;
   203 		return(KErrUnderflow);
   204 		}
   205 
   206 	aTrg=(f.iSign&1) ? -(TInt32)val : val;
   207 
   208 	return(KErrNone);
   209 	}
   210 
   211 #endif //__REALS_MACHINE_CODED__
   212 
   213 #else // __USE_VFP_MATH
   214 
   215 // definitions come from RVCT math library
   216 extern "C" TReal modf(TReal,TReal*);
   217 
   218 EXPORT_C TInt Math::Int(TReal& aTrg, const TReal& aSrc)
   219 	{
   220 	if (Math::IsNaN(aSrc))
   221 		{
   222 		SetNaN(aTrg);
   223 		return KErrArgument;
   224 		}
   225 	if (Math::IsInfinite(aSrc))
   226 		{
   227 		aTrg=aSrc;
   228 		return KErrOverflow;
   229 		}
   230 
   231 	modf(aSrc,&aTrg);
   232 	return KErrNone;
   233 	}
   234 
   235 EXPORT_C TInt Math::Int(TInt32& aTrg, const TReal& aSrc)
   236 	{
   237 	TReal aIntPart;
   238 	TInt r = Math::Int(aIntPart,aSrc);
   239 	if (r==KErrArgument)
   240 		{
   241 		aTrg = 0;
   242 		return r;
   243 		}
   244 	if (aIntPart>KMaxTInt32)
   245 		{
   246 		aTrg = KMaxTInt32;
   247 		return KErrOverflow;
   248 		}
   249 	if (aIntPart<KMinTInt32)
   250 		{
   251 		aTrg = KMinTInt32;
   252 		return KErrUnderflow;
   253 		}
   254 	aTrg = aIntPart;
   255 	return KErrNone;
   256 	}
   257 
   258 EXPORT_C TInt Math::Int(TInt16& aTrg, const TReal& aSrc)
   259 	{
   260 	TReal aIntPart;
   261 	TInt r = Math::Int(aIntPart,aSrc);
   262 	if (r==KErrArgument)
   263 		{
   264 		aTrg = 0;
   265 		return r;
   266 		}
   267 	if (aIntPart>KMaxTInt16)
   268 		{
   269 		aTrg = KMaxTInt16;
   270 		return KErrOverflow;
   271 		}
   272 	if (aIntPart<KMinTInt16)
   273 		{
   274 		aTrg = KMinTInt16;
   275 		return KErrUnderflow;
   276 		}
   277 	aTrg = aIntPart;
   278 	return KErrNone;
   279 	}
   280 
   281 #endif