1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/math/largeint.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,285 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\math\largeint.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "largeint.h"
1.22 +
1.23 +TLargeIntBase::TLargeIntBase(TInt n)
1.24 + : iC(n)
1.25 + {
1.26 + Mem::FillZ(iX,n*sizeof(TUint32));
1.27 + }
1.28 +
1.29 +TLargeIntBase::TLargeIntBase(TInt n, TInt32 aSigned32)
1.30 + : iC(n)
1.31 + {
1.32 + TUint f = (aSigned32<0) ? 0xff : 0;
1.33 + Mem::Fill(iX,n*sizeof(TUint32),f);
1.34 + iX[0]=aSigned32;
1.35 + }
1.36 +
1.37 +TLargeIntBase::TLargeIntBase(TInt n, TUint32 aUnsigned32)
1.38 + : iC(n)
1.39 + {
1.40 + Mem::FillZ(iX,n*sizeof(TUint32));
1.41 + iX[0]=aUnsigned32;
1.42 + }
1.43 +
1.44 +TLargeIntBase::TLargeIntBase(TInt n, const TLargeIntBase& aSrc, TMode aMode)
1.45 + : iC(n)
1.46 + {
1.47 + __ASSERT(aMode==ETruncate||n>=aSrc.iC); // if not truncating, dest can't be shorter than source
1.48 + __ASSERT(aMode!=ETruncate||n<=aSrc.iC); // if truncating, dest can't be longer than source
1.49 + TInt min = Min(n,aSrc.iC);
1.50 + TInt i;
1.51 + for (i=0; i<min; ++i)
1.52 + iX[i] = aSrc.iX[i];
1.53 + if (aMode==ETruncate || n==aSrc.iC)
1.54 + return;
1.55 + TUint32 f = (aMode==ESignExtend && (iX[i-1] & 0x80000000u)) ? 0xffffffffu : 0;
1.56 + for (; i<n; ++i)
1.57 + iX[i] = f;
1.58 + }
1.59 +
1.60 +TLargeIntBase::TLargeIntBase(TInt n, const TUint32* aPtr)
1.61 + : iC(n)
1.62 + {
1.63 + Mem::Copy(iX, aPtr, n*sizeof(TUint32));
1.64 + }
1.65 +
1.66 +TLargeIntBase::TLargeIntBase(TInt n, const Int64& aSigned64)
1.67 + : iC(n)
1.68 + {
1.69 + __ASSERT(n>=2);
1.70 + Mem::Copy(iX, &aSigned64, 8);
1.71 + TUint f = (iX[1] & 0x80000000u) ? 0xff : 0;
1.72 + Mem::Fill(iX+2,(n-2)*sizeof(TUint32),f);
1.73 + }
1.74 +
1.75 +TLargeIntBase::TLargeIntBase(TInt n, const Uint64& aUnsigned64)
1.76 + : iC(n)
1.77 + {
1.78 + __ASSERT(n>=2);
1.79 + Mem::Copy(iX, &aUnsigned64, 8);
1.80 + Mem::FillZ(iX+2,(n-2)*sizeof(TUint32));
1.81 + }
1.82 +
1.83 +void TLargeIntBase::Not()
1.84 + {
1.85 + TInt i;
1.86 + for (i=0; i<iC; ++i)
1.87 + iX[i] = ~iX[i];
1.88 + }
1.89 +
1.90 +void TLargeIntBase::Neg()
1.91 + {
1.92 + Not();
1.93 + Inc();
1.94 + }
1.95 +
1.96 +void TLargeIntBase::Abs()
1.97 + {
1.98 + if (iX[iC-1] & 0x80000000u)
1.99 + Neg();
1.100 + }
1.101 +
1.102 +void TLargeIntBase::Inc()
1.103 + {
1.104 + TInt i;
1.105 + for (i=0; i<iC && ++iX[i]==0; ++i) {}
1.106 + }
1.107 +
1.108 +void TLargeIntBase::Dec()
1.109 + {
1.110 + TInt i;
1.111 + for (i=0; i<iC && --iX[i]==0xffffffffu; ++i) {}
1.112 + }
1.113 +
1.114 +TUint32 TLargeIntBase::Lsl()
1.115 + {
1.116 + TInt i;
1.117 + TUint32 c = 0;
1.118 + for (i=0; i<iC; ++i)
1.119 + {
1.120 + TUint32 x = (iX[i]<<1) | (c>>31);
1.121 + c = iX[i];
1.122 + iX[i] = x;
1.123 + }
1.124 + return c>>31;
1.125 + }
1.126 +
1.127 +TUint32 TLargeIntBase::Lsr()
1.128 + {
1.129 + TInt i;
1.130 + TUint32 c = 0;
1.131 + for (i=iC-1; i>=0; --i)
1.132 + {
1.133 + TUint32 x = (iX[i]>>1) | (c<<31);
1.134 + c = iX[i];
1.135 + iX[i] = x;
1.136 + }
1.137 + return c&1;
1.138 + }
1.139 +
1.140 +TUint32 TLargeIntBase::Asr()
1.141 + {
1.142 + TInt i=iC-1;
1.143 + TUint32 c = iX[i]>>31;
1.144 + for (; i>=0; --i)
1.145 + {
1.146 + TUint32 x = (iX[i]>>1) | (c<<31);
1.147 + c = iX[i];
1.148 + iX[i] = x;
1.149 + }
1.150 + return c&1;
1.151 + }
1.152 +
1.153 +void TLargeIntBase::Lsl(TInt aCount)
1.154 + {
1.155 + while(--aCount>=0)
1.156 + Lsl();
1.157 + }
1.158 +
1.159 +void TLargeIntBase::Lsr(TInt aCount)
1.160 + {
1.161 + while(--aCount>=0)
1.162 + Lsr();
1.163 + }
1.164 +
1.165 +void TLargeIntBase::Asr(TInt aCount)
1.166 + {
1.167 + while(--aCount>=0)
1.168 + Asr();
1.169 + }
1.170 +
1.171 +void TLargeIntBase::Add(const TLargeIntBase& a)
1.172 + {
1.173 + __ASSERT(a.iC==iC);
1.174 + TInt i;
1.175 + TUint32 c = 0;
1.176 + for (i=0; i<iC; ++i)
1.177 + {
1.178 + TUint32 x = iX[i];
1.179 + TUint32 y = a.iX[i];
1.180 + TUint32 s = x + y;
1.181 + iX[i] = (s + (c>>31));
1.182 + TUint32 g = (x & y) | ((x | y) &~ s);
1.183 + TUint32 p = ~s ? 0 : s;
1.184 + c = g | (c & p);
1.185 + }
1.186 + }
1.187 +
1.188 +void TLargeIntBase::Sub(const TLargeIntBase& a)
1.189 + {
1.190 + __ASSERT(a.iC==iC);
1.191 + TInt i;
1.192 + TUint32 c = 0x80000000u;
1.193 + for (i=0; i<iC; ++i)
1.194 + {
1.195 + TUint32 x = iX[i];
1.196 + TUint32 y = ~a.iX[i];
1.197 + TUint32 s = x + y;
1.198 + iX[i] = (s + (c>>31));
1.199 + TUint32 g = (x & y) | ((x | y) &~ s);
1.200 + TUint32 p = ~s ? 0 : s;
1.201 + c = g | (c & p);
1.202 + }
1.203 + }
1.204 +
1.205 +void TLargeIntBase::Mul(const TLargeIntBase& a)
1.206 + {
1.207 + __ASSERT(a.iC==iC);
1.208 + TUint32 temp[64]; // HACK!!
1.209 + Mem::Copy(temp, this, (iC+1)*sizeof(TUint32));
1.210 + TLargeIntBase& b = *(TLargeIntBase*)temp;
1.211 + new (this) TLargeIntBase(iC,TUint32(0u));
1.212 + TInt i;
1.213 + for (i=0; i<32*iC; ++i)
1.214 + {
1.215 + Lsl();
1.216 + if (b.Lsl())
1.217 + Add(a);
1.218 + }
1.219 + }
1.220 +
1.221 +void TLargeIntBase::DivU(const TLargeIntBase& aDivisor, TLargeIntBase& aRem)
1.222 + {
1.223 + __ASSERT(aDivisor.iC==iC);
1.224 + __ASSERT(aRem.iC==iC);
1.225 + new (&aRem) TLargeIntBase(iC,TUint32(0u));
1.226 + TInt i;
1.227 + for (i=0; i<iC*32; ++i)
1.228 + {
1.229 + aRem.Lsl();
1.230 + if (Lsl())
1.231 + aRem.Inc();
1.232 + if (aRem.Hs(aDivisor))
1.233 + aRem.Sub(aDivisor), Inc();
1.234 + }
1.235 + }
1.236 +
1.237 +void TLargeIntBase::DivS(const TLargeIntBase& aDivisor, TLargeIntBase& aRem)
1.238 + {
1.239 + __ASSERT(aDivisor.iC==iC);
1.240 + __ASSERT(aRem.iC==iC);
1.241 + TUint32 temp[64]; // HACK!!
1.242 + Mem::Copy(temp, &aDivisor, (iC+1)*sizeof(TUint32));
1.243 + TLargeIntBase& divisor = *(TLargeIntBase*)temp;
1.244 + TUint32 rs = iX[iC-1];
1.245 + TUint32 qs = divisor.iX[iC-1] ^ rs;
1.246 + Abs();
1.247 + divisor.Abs();
1.248 + DivU(divisor, aRem);
1.249 + if (rs & 0x80000000u)
1.250 + aRem.Neg();
1.251 + if (qs & 0x80000000u)
1.252 + Neg();
1.253 + }
1.254 +
1.255 +TInt TLargeIntBase::CompareU(const TLargeIntBase& a) const
1.256 + {
1.257 + __ASSERT(a.iC==iC);
1.258 + TInt i;
1.259 + for (i=iC-1; i>=0; --i)
1.260 + {
1.261 + TUint32 x = iX[i];
1.262 + TUint32 y = a.iX[i];
1.263 + if (x>y)
1.264 + return 1;
1.265 + if (x<y)
1.266 + return -1;
1.267 + }
1.268 + return 0;
1.269 + }
1.270 +
1.271 +TInt TLargeIntBase::CompareS(const TLargeIntBase& a) const
1.272 + {
1.273 + __ASSERT(a.iC==iC);
1.274 + TInt i;
1.275 + TUint32 m = 0x80000000u;
1.276 + for (i=iC-1; i>=0; --i)
1.277 + {
1.278 + TUint32 x = iX[i] ^ m;
1.279 + TUint32 y = a.iX[i] ^ m;
1.280 + m = 0;
1.281 + if (x>y)
1.282 + return 1;
1.283 + if (x<y)
1.284 + return -1;
1.285 + }
1.286 + return 0;
1.287 + }
1.288 +