Update contrib.
2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "tbasicmathsfb.h"
25 CTestAction* CBasicMathsFB::NewL(RFs& aFs, CConsoleBase& aConsole,
26 Output& aOut, const TTestActionSpec& aTestActionSpec)
28 CTestAction* self = CBasicMathsFB::NewLC(aFs, aConsole,
29 aOut, aTestActionSpec);
34 CTestAction* CBasicMathsFB::NewLC(RFs& aFs, CConsoleBase& aConsole,
35 Output& aOut, const TTestActionSpec& aTestActionSpec)
37 CBasicMathsFB* self = new(ELeave) CBasicMathsFB(aFs, aConsole, aOut);
38 CleanupStack::PushL(self);
39 self->ConstructL(aTestActionSpec);
43 CBasicMathsFB::~CBasicMathsFB()
48 CBasicMathsFB::CBasicMathsFB(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
49 : CTestAction(aConsole, aOut), iFs(aFs)
53 void CBasicMathsFB::ConstructL(const TTestActionSpec& aTestActionSpec)
55 CTestAction::ConstructL(aTestActionSpec);
57 iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length());
58 iBody->Des().Copy(aTestActionSpec.iActionBody);
60 //HBufC8* length = Input::ParseElementHexL(*iBody, _L8("<bits>"));
61 TUint bits = Input::ParseIntElement(*iBody, _L8("<bits>"), _L8("</bits>"));
62 // the final /7 gives the number of times we have to increment by 7 to get
63 // to that number of bytes and hence bits.
64 iIterations = ((bits+7)/8)/7 + 1;
67 void CBasicMathsFB::DoPerformPrerequisite(TRequestStatus& aStatus)
69 TRequestStatus* status = &aStatus;
70 User::RequestComplete(status, KErrNone);
71 iActionState = CTestAction::EAction;
74 void CBasicMathsFB::DoPerformPostrequisite(TRequestStatus& aStatus)
76 TRequestStatus* status = &aStatus;
78 User::RequestComplete(status, KErrNone);
81 void CBasicMathsFB::DoReportAction(void)
85 void CBasicMathsFB::DoCheckResult(TInt)
89 void CBasicMathsFB::PerformAction(TRequestStatus& aStatus)
92 TRequestStatus* status = &aStatus;
95 //min max values for NewRandomLC call
96 RInteger min = RInteger::NewL(10);
97 CleanupStack::PushL(min);
98 RInteger max = RInteger::NewL(100);
99 CleanupStack::PushL(max);
101 //Generate iIterations*7 byte random sequences we are using 7 as it's a generator
102 //mod 8. Thus we'll cycle through every value (0-7) every 8 iterations.
103 //This gives us a better feeling that certain byte lengths (and thus bit
104 //lengths as the byte is chosen randomly) don't have errors.
105 for(TUint i=1; i<iIterations; i++)
107 HBufC8* buf = HBufC8::NewMaxLC(i*7);
108 TPtr8 ptr = buf->Des();
109 TRandom::RandomL(ptr);
111 //This is this iteration's random number
112 RInteger initial = RInteger::NewL(ptr);
113 CleanupStack::PushL(initial);
115 //get a number x | 10 < x < 100
116 RInteger crange = RInteger::NewRandomL(min, max);
117 CleanupStack::PushL(crange);
118 TUint range = crange.ConvertToLongL();
119 CleanupStack::PopAndDestroy(); //crange
121 AddSub(initial, range);
122 MulDiv(initial, range);
124 CleanupStack::PopAndDestroy(); //initial
125 CleanupStack::PopAndDestroy();//buf
126 iConsole.Printf(_L("."));
129 //Test a single iteration where the initial random number is less than a
130 //word so the division and modulo routines that take words rather than
134 //This is this iteration's random number
135 RInteger initial = RInteger::NewRandomL(31);
136 CleanupStack::PushL(initial);
137 //get a number x | 10 < x < 100
138 RInteger crange = RInteger::NewRandomL(min, max);
139 CleanupStack::PushL(crange);
140 TUint range = crange.ConvertToLongL();
141 CleanupStack::PopAndDestroy(&crange); //crange
143 AddSub(initial, range);
144 MulDiv(initial, range);
145 CleanupStack::PopAndDestroy(&initial); //initial
146 iConsole.Printf(_L("."));
149 CleanupStack::PopAndDestroy();//max
150 CleanupStack::PopAndDestroy(); //min
154 User::RequestComplete(status, KErrNone);
155 iActionState = CTestAction::EPostrequisite;
159 void CBasicMathsFB::AddSub(const TInteger& aInitial, TUint aRange)
162 //This is the copy we are going to do stuff to
163 RInteger a = RInteger::NewL(aInitial);
164 CleanupStack::PushL(a);
166 // compute a*aRange using doubling
174 RInteger b = RInteger::NewL(a);
175 CleanupStack::PushL(b);
176 //compute (a*aRange)/aRange using subtraction
177 for(j=1; j<aRange; j++)
181 // b should be the same as the initial value
185 iOut.writeString(_L("AddSub Failure:"));
189 RInteger c = RInteger::NewL(aInitial);
190 CleanupStack::PushL(c);
191 // compute a*aRange using normal multiplication
194 // c and a should now be the same
200 RInteger d = RInteger::NewL(a);
201 CleanupStack::PushL(d);
202 //compute (a*aRange)/aRange using normal division
208 RInteger e = RInteger::NewL(a);
209 CleanupStack::PushL(e);
211 // (a*aRange)%aRange == 0
216 CleanupStack::PopAndDestroy(5); //e,d,c,b,a
220 void CBasicMathsFB::MulDiv(const TInteger& aInitial, TUint aRange)
223 //This is the copy we are going to do stuff to
224 RInteger a = RInteger::NewL(aInitial);
225 CleanupStack::PushL(a);
227 //compute a = aInitial^aRange using repeated multiplication
235 RInteger b = RInteger::NewL(a);
236 CleanupStack::PushL(b);
237 //try to find aInitial by repeatedly dividing b by aInitial aRange times
238 for(j=1; j<aRange; j++)
240 TRAPD(res, b /= aInitial);
241 //the first time through aInitial is 0 so this is expected
242 if(res == KErrDivideByZero && aInitial.IsZero())
246 else if(res == KErrDivideByZero && aInitial.NotZero())
250 else if(res != KErrNone)
255 // b should be the same as the initial value
261 //tests division by something smaller than a word
262 if(aInitial.WordCount() <= 1)
264 RInteger dividend = RInteger::NewL(a);
265 CleanupStack::PushL(dividend);
266 for(j=1; j<aRange; j++)
269 //try to find aInitial by repeatedly dividing dividend by aInitial aRange times
270 TRAPD(res, quotient = dividend.DividedByL(aInitial.ConvertToLongL()));
271 //the first time through aInitial is 0 so this is expected
272 if(res == KErrDivideByZero && aInitial.IsZero())
276 else if(res == KErrDivideByZero && aInitial.NotZero())
280 else if(res != KErrNone)
284 dividend.Set(quotient);
286 if( dividend != aInitial )
292 TRAPD(res, remainder = a.ModuloL(aInitial.ConvertToLongL()));
293 //the first time through aInitial is 0
294 if(res != KErrDivideByZero && res != KErrNone)
298 else if(res == KErrDivideByZero && aInitial.NotZero())
302 //else we have an expected divide by zero, ignore it.
308 CleanupStack::PopAndDestroy(÷nd);
311 RInteger c = RInteger::NewL(aRange);
312 CleanupStack::PushL(c);
313 RInteger d = aInitial.ExponentiateL(c);
314 CleanupStack::PushL(d);
315 // c and a should now be the same
321 RInteger e = RInteger::NewL(a);
322 CleanupStack::PushL(e);
323 TRAPD(res, e %= aInitial);
324 //the first time through aInitial is 0
325 if(res != KErrDivideByZero && res != KErrNone)
329 else if(res == KErrDivideByZero && aInitial.NotZero())
333 //else we have an expected divide by zero, ignore it.
335 // (aInitial^aRange)%aInitial == 0
340 CleanupStack::PopAndDestroy(5);//e,d,c,b,a
344 void CBasicMathsFB::MiscDivL()
350 TInt dividendInt = 10;
352 RInteger dividend = RInteger::NewL(seed);
353 CleanupStack::PushL(dividend);
355 TInt longInt = dividend.ConvertToLongL();
357 // Test for inequality FALSE
358 TBool res0 = dividend != dividendInt;
364 // Test for inequality TRUE
365 res0 = dividend != TInt(diviser);
371 // Test for equality TRUE
372 res0 = dividend >= dividend;
379 CleanupStack::PushL(quotient);
381 TRAPD(res, quotient = dividend.DividedByL(diviser));
386 else if (quotient != (dividendInt/diviser))
391 // Test for greater value TRUE and equality FALSE
392 res0 = dividend >= quotient;
398 // Test for greater value FALSE and equality FALSE
399 res0 = quotient >= dividend;
406 TRAPD(res1, dividend /= dividendInt);
407 if (res1 != KErrNone)
411 else if (dividend != (dividendInt/seed))
416 // 1 % 10 = 1 (dividend = 1, due to last step)
417 TRAPD(res2, dividend %= dividendInt);
418 if (res2 != KErrNone)
422 else if (dividend != (dividendInt/seed))
427 // 1 x 1 = 1 (dividend = 1, due to last step)
428 RInteger squaredInt = dividend.SquaredL();
429 CleanupStack::PushL(squaredInt);
430 if ( squaredInt != (dividendInt/seed))
435 RInteger expSeed = RInteger::NewL(10);
436 CleanupStack::PushL(expSeed);
437 RInteger exponent = RInteger::NewL(3);
438 CleanupStack::PushL(exponent);
440 CleanupStack::PushL(expResult);
441 TRAPD(res3, expResult = expSeed.ExponentiateL(exponent));
442 if (res3 != KErrNone)
446 else if (expResult != (10*10*10))
451 CleanupStack::PopAndDestroy(6, ÷nd); // dividend, quotient, squardInt, expSeed, exponent, expResult