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