symport/e32/euser/maths/um_int.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_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