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 |
|