symport/e32/euser/maths/um_int.cpp
changeset 1 0a7b44b10206
child 2 806186ab5e14
--- /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<TUint32>(mask >> 32);
+	f.iMantLo &= static_cast<TUint32>(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 (aIntPart<KMinTInt32)
+		{
+		aTrg = KMinTInt32;
+		return KErrUnderflow;
+		}
+	aTrg = aIntPart;
+	return KErrNone;
+	}
+
+EXPORT_C TInt Math::Int(TInt16& aTrg, const TReal& aSrc)
+	{
+	TReal aIntPart;
+	TInt r = Math::Int(aIntPart,aSrc);
+	if (r==KErrArgument)
+		{
+		aTrg = 0;
+		return r;
+		}
+	if (aIntPart>KMaxTInt16)
+		{
+		aTrg = KMaxTInt16;
+		return KErrOverflow;
+		}
+	if (aIntPart<KMinTInt16)
+		{
+		aTrg = KMinTInt16;
+		return KErrUnderflow;
+		}
+	aTrg = aIntPart;
+	return KErrNone;
+	}
+
+#endif