os/kernelhwsrv/kerneltest/e32test/math/largeint.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
// e32test\math\largeint.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "largeint.h"
sl@0
    19
sl@0
    20
TLargeIntBase::TLargeIntBase(TInt n)
sl@0
    21
	: iC(n)
sl@0
    22
	{
sl@0
    23
	Mem::FillZ(iX,n*sizeof(TUint32));
sl@0
    24
	}
sl@0
    25
sl@0
    26
TLargeIntBase::TLargeIntBase(TInt n, TInt32 aSigned32)
sl@0
    27
	: iC(n)
sl@0
    28
	{
sl@0
    29
	TUint f = (aSigned32<0) ? 0xff : 0;
sl@0
    30
	Mem::Fill(iX,n*sizeof(TUint32),f);
sl@0
    31
	iX[0]=aSigned32;
sl@0
    32
	}
sl@0
    33
sl@0
    34
TLargeIntBase::TLargeIntBase(TInt n, TUint32 aUnsigned32)
sl@0
    35
	: iC(n)
sl@0
    36
	{
sl@0
    37
	Mem::FillZ(iX,n*sizeof(TUint32));
sl@0
    38
	iX[0]=aUnsigned32;
sl@0
    39
	}
sl@0
    40
sl@0
    41
TLargeIntBase::TLargeIntBase(TInt n, const TLargeIntBase& aSrc, TMode aMode)
sl@0
    42
	: iC(n)
sl@0
    43
	{
sl@0
    44
	__ASSERT(aMode==ETruncate||n>=aSrc.iC);	// if not truncating, dest can't be shorter than source
sl@0
    45
	__ASSERT(aMode!=ETruncate||n<=aSrc.iC);	// if truncating, dest can't be longer than source
sl@0
    46
	TInt min = Min(n,aSrc.iC);
sl@0
    47
	TInt i;
sl@0
    48
	for (i=0; i<min; ++i)
sl@0
    49
		iX[i] = aSrc.iX[i];
sl@0
    50
	if (aMode==ETruncate || n==aSrc.iC)
sl@0
    51
		return;
sl@0
    52
	TUint32 f = (aMode==ESignExtend && (iX[i-1] & 0x80000000u)) ? 0xffffffffu : 0;
sl@0
    53
	for (; i<n; ++i)
sl@0
    54
		iX[i] = f;
sl@0
    55
	}
sl@0
    56
sl@0
    57
TLargeIntBase::TLargeIntBase(TInt n, const TUint32* aPtr)
sl@0
    58
	: iC(n)
sl@0
    59
	{
sl@0
    60
	Mem::Copy(iX, aPtr, n*sizeof(TUint32));
sl@0
    61
	}
sl@0
    62
sl@0
    63
TLargeIntBase::TLargeIntBase(TInt n, const Int64& aSigned64)
sl@0
    64
	: iC(n)
sl@0
    65
	{
sl@0
    66
	__ASSERT(n>=2);
sl@0
    67
	Mem::Copy(iX, &aSigned64, 8);
sl@0
    68
	TUint f = (iX[1] & 0x80000000u) ? 0xff : 0;
sl@0
    69
	Mem::Fill(iX+2,(n-2)*sizeof(TUint32),f);
sl@0
    70
	}
sl@0
    71
sl@0
    72
TLargeIntBase::TLargeIntBase(TInt n, const Uint64& aUnsigned64)
sl@0
    73
	: iC(n)
sl@0
    74
	{
sl@0
    75
	__ASSERT(n>=2);
sl@0
    76
	Mem::Copy(iX, &aUnsigned64, 8);
sl@0
    77
	Mem::FillZ(iX+2,(n-2)*sizeof(TUint32));
sl@0
    78
	}
sl@0
    79
sl@0
    80
void TLargeIntBase::Not()
sl@0
    81
	{
sl@0
    82
	TInt i;
sl@0
    83
	for (i=0; i<iC; ++i)
sl@0
    84
		iX[i] = ~iX[i];
sl@0
    85
	}
sl@0
    86
sl@0
    87
void TLargeIntBase::Neg()
sl@0
    88
	{
sl@0
    89
	Not();
sl@0
    90
	Inc();
sl@0
    91
	}
sl@0
    92
sl@0
    93
void TLargeIntBase::Abs()
sl@0
    94
	{
sl@0
    95
	if (iX[iC-1] & 0x80000000u)
sl@0
    96
		Neg();
sl@0
    97
	}
sl@0
    98
sl@0
    99
void TLargeIntBase::Inc()
sl@0
   100
	{
sl@0
   101
	TInt i;
sl@0
   102
	for (i=0; i<iC && ++iX[i]==0; ++i) {}
sl@0
   103
	}
sl@0
   104
sl@0
   105
void TLargeIntBase::Dec()
sl@0
   106
	{
sl@0
   107
	TInt i;
sl@0
   108
	for (i=0; i<iC && --iX[i]==0xffffffffu; ++i) {}
sl@0
   109
	}
sl@0
   110
sl@0
   111
TUint32 TLargeIntBase::Lsl()
sl@0
   112
	{
sl@0
   113
	TInt i;
sl@0
   114
	TUint32 c = 0;
sl@0
   115
	for (i=0; i<iC; ++i)
sl@0
   116
		{
sl@0
   117
		TUint32 x = (iX[i]<<1) | (c>>31);
sl@0
   118
		c = iX[i];
sl@0
   119
		iX[i] = x;
sl@0
   120
		}
sl@0
   121
	return c>>31;
sl@0
   122
	}
sl@0
   123
sl@0
   124
TUint32 TLargeIntBase::Lsr()
sl@0
   125
	{
sl@0
   126
	TInt i;
sl@0
   127
	TUint32 c = 0;
sl@0
   128
	for (i=iC-1; i>=0; --i)
sl@0
   129
		{
sl@0
   130
		TUint32 x = (iX[i]>>1) | (c<<31);
sl@0
   131
		c = iX[i];
sl@0
   132
		iX[i] = x;
sl@0
   133
		}
sl@0
   134
	return c&1;
sl@0
   135
	}
sl@0
   136
sl@0
   137
TUint32 TLargeIntBase::Asr()
sl@0
   138
	{
sl@0
   139
	TInt i=iC-1;
sl@0
   140
	TUint32 c = iX[i]>>31;
sl@0
   141
	for (; i>=0; --i)
sl@0
   142
		{
sl@0
   143
		TUint32 x = (iX[i]>>1) | (c<<31);
sl@0
   144
		c = iX[i];
sl@0
   145
		iX[i] = x;
sl@0
   146
		}
sl@0
   147
	return c&1;
sl@0
   148
	}
sl@0
   149
sl@0
   150
void TLargeIntBase::Lsl(TInt aCount)
sl@0
   151
	{
sl@0
   152
	while(--aCount>=0)
sl@0
   153
		Lsl();
sl@0
   154
	}
sl@0
   155
sl@0
   156
void TLargeIntBase::Lsr(TInt aCount)
sl@0
   157
	{
sl@0
   158
	while(--aCount>=0)
sl@0
   159
		Lsr();
sl@0
   160
	}
sl@0
   161
sl@0
   162
void TLargeIntBase::Asr(TInt aCount)
sl@0
   163
	{
sl@0
   164
	while(--aCount>=0)
sl@0
   165
		Asr();
sl@0
   166
	}
sl@0
   167
sl@0
   168
void TLargeIntBase::Add(const TLargeIntBase& a)
sl@0
   169
	{
sl@0
   170
	__ASSERT(a.iC==iC);
sl@0
   171
	TInt i;
sl@0
   172
	TUint32 c = 0;
sl@0
   173
	for (i=0; i<iC; ++i)
sl@0
   174
		{
sl@0
   175
		TUint32 x = iX[i];
sl@0
   176
		TUint32 y = a.iX[i];
sl@0
   177
		TUint32 s = x + y;
sl@0
   178
		iX[i] = (s + (c>>31));
sl@0
   179
		TUint32 g = (x & y) | ((x | y) &~ s);
sl@0
   180
		TUint32 p = ~s ? 0 : s;
sl@0
   181
		c = g | (c & p);
sl@0
   182
		}
sl@0
   183
	}
sl@0
   184
sl@0
   185
void TLargeIntBase::Sub(const TLargeIntBase& a)
sl@0
   186
	{
sl@0
   187
	__ASSERT(a.iC==iC);
sl@0
   188
	TInt i;
sl@0
   189
	TUint32 c = 0x80000000u;
sl@0
   190
	for (i=0; i<iC; ++i)
sl@0
   191
		{
sl@0
   192
		TUint32 x = iX[i];
sl@0
   193
		TUint32 y = ~a.iX[i];
sl@0
   194
		TUint32 s = x + y;
sl@0
   195
		iX[i] = (s + (c>>31));
sl@0
   196
		TUint32 g = (x & y) | ((x | y) &~ s);
sl@0
   197
		TUint32 p = ~s ? 0 : s;
sl@0
   198
		c = g | (c & p);
sl@0
   199
		}
sl@0
   200
	}
sl@0
   201
sl@0
   202
void TLargeIntBase::Mul(const TLargeIntBase& a)
sl@0
   203
	{
sl@0
   204
	__ASSERT(a.iC==iC);
sl@0
   205
	TUint32 temp[64];	// HACK!!
sl@0
   206
	Mem::Copy(temp, this, (iC+1)*sizeof(TUint32));
sl@0
   207
	TLargeIntBase& b = *(TLargeIntBase*)temp;
sl@0
   208
	new (this) TLargeIntBase(iC,TUint32(0u));
sl@0
   209
	TInt i;
sl@0
   210
	for (i=0; i<32*iC; ++i)
sl@0
   211
		{
sl@0
   212
		Lsl();
sl@0
   213
		if (b.Lsl())
sl@0
   214
			Add(a);
sl@0
   215
		}
sl@0
   216
	}
sl@0
   217
sl@0
   218
void TLargeIntBase::DivU(const TLargeIntBase& aDivisor, TLargeIntBase& aRem)
sl@0
   219
	{
sl@0
   220
	__ASSERT(aDivisor.iC==iC);
sl@0
   221
	__ASSERT(aRem.iC==iC);
sl@0
   222
	new (&aRem) TLargeIntBase(iC,TUint32(0u));
sl@0
   223
	TInt i;
sl@0
   224
	for (i=0; i<iC*32; ++i)
sl@0
   225
		{
sl@0
   226
		aRem.Lsl();
sl@0
   227
		if (Lsl())
sl@0
   228
			aRem.Inc();
sl@0
   229
		if (aRem.Hs(aDivisor))
sl@0
   230
			aRem.Sub(aDivisor), Inc();
sl@0
   231
		}
sl@0
   232
	}
sl@0
   233
sl@0
   234
void TLargeIntBase::DivS(const TLargeIntBase& aDivisor, TLargeIntBase& aRem)
sl@0
   235
	{
sl@0
   236
	__ASSERT(aDivisor.iC==iC);
sl@0
   237
	__ASSERT(aRem.iC==iC);
sl@0
   238
	TUint32 temp[64];	// HACK!!
sl@0
   239
	Mem::Copy(temp, &aDivisor, (iC+1)*sizeof(TUint32));
sl@0
   240
	TLargeIntBase& divisor = *(TLargeIntBase*)temp;
sl@0
   241
	TUint32 rs = iX[iC-1];
sl@0
   242
	TUint32 qs = divisor.iX[iC-1] ^ rs;
sl@0
   243
	Abs();
sl@0
   244
	divisor.Abs();
sl@0
   245
	DivU(divisor, aRem);
sl@0
   246
	if (rs & 0x80000000u)
sl@0
   247
		aRem.Neg();
sl@0
   248
	if (qs & 0x80000000u)
sl@0
   249
		Neg();
sl@0
   250
	}
sl@0
   251
sl@0
   252
TInt TLargeIntBase::CompareU(const TLargeIntBase& a) const
sl@0
   253
	{
sl@0
   254
	__ASSERT(a.iC==iC);
sl@0
   255
	TInt i;
sl@0
   256
	for (i=iC-1; i>=0; --i)
sl@0
   257
		{
sl@0
   258
		TUint32 x = iX[i];
sl@0
   259
		TUint32 y = a.iX[i];
sl@0
   260
		if (x>y)
sl@0
   261
			return 1;
sl@0
   262
		if (x<y)
sl@0
   263
			return -1;
sl@0
   264
		}
sl@0
   265
	return 0;
sl@0
   266
	}
sl@0
   267
sl@0
   268
TInt TLargeIntBase::CompareS(const TLargeIntBase& a) const
sl@0
   269
	{
sl@0
   270
	__ASSERT(a.iC==iC);
sl@0
   271
	TInt i;
sl@0
   272
	TUint32 m = 0x80000000u;
sl@0
   273
	for (i=iC-1; i>=0; --i)
sl@0
   274
		{
sl@0
   275
		TUint32 x = iX[i] ^ m;
sl@0
   276
		TUint32 y = a.iX[i] ^ m;
sl@0
   277
		m = 0;
sl@0
   278
		if (x>y)
sl@0
   279
			return 1;
sl@0
   280
		if (x<y)
sl@0
   281
			return -1;
sl@0
   282
		}
sl@0
   283
	return 0;
sl@0
   284
	}
sl@0
   285