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