diff -r c55016431358 -r 0a7b44b10206 symport/e32/euser/maths/um_int.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symport/e32/euser/maths/um_int.cpp Thu Jun 25 15:59:54 2009 +0100 @@ -0,0 +1,281 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Symbian Foundation License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\euser\maths\um_int.cpp +// Writes the integer part aTrg to aSrc (aSrc is either TReal,TInt16 orTInt32) +// +// + +#include "um_std.h" + +#if defined(__USE_VFP_MATH) && !defined(__CPU_HAS_VFP) +#error __USE_VFP_MATH was defined but not __CPU_HAS_VFP - impossible combination, check variant.mmh +#endif + +#ifndef __USE_VFP_MATH + +#ifndef __REALS_MACHINE_CODED__ +EXPORT_C TInt Math::Int(TReal &aTrg,const TReal &aSrc) +/** +Calculates the integer part of a number. + +The integer part is that before a decimal point. +Truncation is toward zero, so that +int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1. + + +@param aTrg A reference containing the result. +@param aSrc The number whose integer part is required. + +@return KErrNone if successful, otherwise another of + the system-wide error codes. +*/ + { + TRealX f; + TInt ret=f.Set(aSrc); + if (ret!=KErrNone) + { + aTrg=aSrc; + return(ret); + } + TInt intbits=f.iExp-0x7FFE; // number of integer bits in mantissa + if (intbits<=0) + { + SetZero(aTrg,f.iSign&1); // no integer part + return(KErrNone); + } + if (intbits>=KMantissaBits) + { + aTrg=aSrc; // fractional part is outside range of significance + return(KErrNone); + } + + TUint64 mask = ~(UI64LIT(0)); + mask <<= (64 - intbits); + + f.iMantHi &= static_cast(mask >> 32); + f.iMantLo &= static_cast(mask); + + f.GetTReal(aTrg); + return(KErrNone); + } + + + + +EXPORT_C TInt Math::Int(TInt16 &aTrg,const TReal &aSrc) +/** +Calculates the integer part of a number. + +The integer part is that before a decimal point. +Truncation is toward zero, so that +int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1. + +This function is suitable when the result is known to be small enough +for a 16-bit signed integer. + +@param aTrg A reference containing the result. +@param aSrc The number whose integer part is required. + +@return KErrNone if successful, otherwise another of + the system-wide error codes. +*/ +// +// If the integer part of aSrc is in the range -32768 to +32767 +// inclusive, write the integer part to the TInt16 at aTrg +// Negative numbers are rounded towards zero. +// If an overflow or underflow occurs, aTrg is set to the max/min value +// + { + TRealX f; + TInt ret=f.Set(aSrc); + + if (ret==KErrArgument) + { + aTrg=0; + return(ret); + } + + TInt intbits=f.iExp-0x7FFE; // number of integer bits in mantissa + + if (intbits<=0) + { + aTrg=0; + return(KErrNone); + } + + if (intbits>16) + { + aTrg=(TInt16)((f.iSign&1) ? KMinTInt16 : KMaxTInt16); + return((f.iSign&1) ? KErrUnderflow : KErrOverflow); + } + + TUint val = f.iMantHi >> (32 - intbits); + + if ((f.iSign&1)==0 && val>(TUint)KMaxTInt16) + { + aTrg=TInt16(KMaxTInt16); + return(KErrOverflow); + } + + if ((f.iSign&1) && val>(TUint)(KMaxTInt16+1)) + { + aTrg=TInt16(KMinTInt16); + return(KErrUnderflow); + } + + aTrg = (f.iSign&1) ? (TInt16)(-(TInt)val) : (TInt16)val; + + return(KErrNone); + } + + + + +EXPORT_C TInt Math::Int(TInt32 &aTrg,const TReal &aSrc) +/** +Calculates the integer part of a number. + +The integer part is that before a decimal point. +Truncation is toward zero, so that +int(2.4)=2, int(2)=2, int(-1)=-1, int(-1.4)=-1, int(-1.999)=-1. + +This function is suitable when the result is known to be small enough +for a 32-bit signed integer. + +@param aTrg A reference containing the result. +@param aSrc The number whose integer part is required. + +@return KErrNone if successful, otherwise another of + the system-wide error codes. +*/ +// +// If the integer part of the float is in the range -2147483648 to +2147483647 +// inclusive, write the integer part to the TInt32 at aTrg +// Negative numbers are rounded towards zero. +// If an overflow or underflow occurs, aTrg is set to the max/min value +// + { + TRealX f; + TInt ret=f.Set(aSrc); + + if (ret==KErrArgument) + { + aTrg=0; + return(ret); + } + + TInt intbits=f.iExp-0x7FFE; // number of integer bits in mantissa + + if (intbits<=0) + { + aTrg=0; + return(KErrNone); + } + + if (intbits>32) + { + aTrg=((f.iSign&1) ? KMinTInt32 : KMaxTInt32); + return((f.iSign&1) ? KErrUnderflow : KErrOverflow); + } + + TUint val = f.iMantHi >> (32 - intbits); + + if ((f.iSign&1)==0 && val>(TUint)KMaxTInt32) + { + aTrg=KMaxTInt32; + return(KErrOverflow); + } + + if ((f.iSign&1) && val>((TUint)KMaxTInt32+1)) + { + aTrg=KMinTInt32; + return(KErrUnderflow); + } + + aTrg=(f.iSign&1) ? -(TInt32)val : val; + + return(KErrNone); + } + +#endif //__REALS_MACHINE_CODED__ + +#else // __USE_VFP_MATH + +// definitions come from RVCT math library +extern "C" TReal modf(TReal,TReal*); + +EXPORT_C TInt Math::Int(TReal& aTrg, const TReal& aSrc) + { + if (Math::IsNaN(aSrc)) + { + SetNaN(aTrg); + return KErrArgument; + } + if (Math::IsInfinite(aSrc)) + { + aTrg=aSrc; + return KErrOverflow; + } + + modf(aSrc,&aTrg); + return KErrNone; + } + +EXPORT_C TInt Math::Int(TInt32& aTrg, const TReal& aSrc) + { + TReal aIntPart; + TInt r = Math::Int(aIntPart,aSrc); + if (r==KErrArgument) + { + aTrg = 0; + return r; + } + if (aIntPart>KMaxTInt32) + { + aTrg = KMaxTInt32; + return KErrOverflow; + } + if (aIntPartKMaxTInt16) + { + aTrg = KMaxTInt16; + return KErrOverflow; + } + if (aIntPart