Update contrib.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\math\t_roundtrip.cpp
15 // Tests round-trip convertibility of double->string->double
19 #define __E32TEST_EXTENSION__
23 //#define __ALWAYS_PRINT__
25 RTest test(_L("T_ROUNDTRIP"));
27 void PrintRealHex(const char* aTitle, const TReal& aIn)
29 volatile TUint32* in = (volatile TUint32*)&aIn;
30 #ifdef __DOUBLE_WORDS_SWAPPED__
39 title.Copy(TPtrC8((const TUint8*)aTitle));
40 test.Printf(_L("%S%08x %08x\n"), &title, high, low);
43 TInt RoundTrip(TReal& aOut, const TReal& aIn)
47 fmt.iType = KRealFormatExponent | KRealInjectiveLimit | KUseSigFigs | KDoNotUseTriads | KAllowThreeDigitExp;
49 fmt.iPlaces = KIEEEDoubleInjectivePrecision;
51 #ifdef __ALWAYS_PRINT__
52 PrintRealHex("Input : ", aIn);
54 TInt r = text.Num(aIn, fmt);
57 test.Printf(_L("Result %d (Num)\n"), r);
60 #ifdef __ALWAYS_PRINT__
63 test.Printf(_L("Text : %S\n"), &text16);
69 test.Printf(_L("Result %d (Val)\n"), r);
72 #ifdef __ALWAYS_PRINT__
73 PrintRealHex("Output: ", aOut);
75 volatile TUint32* in = (volatile TUint32*)&aIn;
76 volatile TUint32* out = (volatile TUint32*)&aOut;
77 if (in[0]!=out[0] || in[1]!=out[1])
79 test.Printf(_L("Unsuccessful\n"));
80 #ifndef __ALWAYS_PRINT__
81 PrintRealHex("Input : ", aIn);
84 test.Printf(_L("Text : %S\n"), &text16);
85 PrintRealHex("Output: ", aOut);
92 const TUint64 KMantissaOverflow = UI64LIT(0x20000000000000); // 2^53
93 const TUint64 KMantissaThreshold = UI64LIT(0x10000000000000); // 2^52
98 enum {EMinExp=0, EMinNormExp=1, EMaxNormExp=2046, EMaxExp=2047};
106 TUint64 iMant; // if iExp>0 2^52<=iMant<2^53 else 0<=iMant<2^52
107 TInt iExp; // 0 < iExp < 2047
118 R::R(const TReal& aIn)
120 const volatile TUint32* in = (const volatile TUint32*)&aIn;
121 #ifdef __DOUBLE_WORDS_SWAPPED__
122 TUint32 high = in[0];
125 TUint32 high = in[1];
129 iExp = (high >> 20) & EMaxExp;
130 iMant = MAKE_TUINT64(high, low);
134 iMant += KMantissaThreshold;
137 TReal R::Value() const
139 TUint32 high = iSign ? 1 : 0;
142 TUint32 mh = I64HIGH(iMant);
145 TUint32 low = I64LOW(iMant);
147 union {TReal iReal; TUint32 iX[2];} result;
148 #ifdef __DOUBLE_WORDS_SWAPPED__
162 if (++iMant == KMantissaOverflow)
165 if (++iExp == EMaxExp)
170 if (++iMant == KMantissaThreshold)
179 if (iMant == KMantissaThreshold)
188 if (--iMant < KMantissaThreshold)
199 return KErrUnderflow;
204 void DoTest(R& aR, TInt& aErrorCount)
208 r = RoundTrip(out, aR.Value());
213 if (R1.Next()==KErrNone)
215 r = RoundTrip(out, R1.Value());
219 if (R2.Prev()==KErrNone)
221 r = RoundTrip(out, R2.Value());
227 void DoTest(TInt aExp, TInt& aErrorCount)
231 x.iMant = KMantissaThreshold;
236 DoTest(x, aErrorCount);
241 DoTest(x, aErrorCount);
245 void DoTestPow10(TInt aPow, TInt& aErrorCount)
248 TInt r = Math::Pow10(r64, aPow);
252 DoTest(x, aErrorCount);
255 void DoTestRandom(TInt& aErrorCount)
257 static TInt64 randSeed = I64LIT(0x3333333333333333);
259 x.iExp = Math::Rand(randSeed) & R::EMaxExp;
260 x.iMant = ((TUint64)Math::Rand(randSeed) << 32) | (TUint64)Math::Rand(randSeed);
261 while (x.iMant > KMantissaThreshold)
263 x.iSign = Math::Rand(randSeed) & 0x1;
264 DoTest(x, aErrorCount);
270 test.Start(_L("Testing conversion from double->string->double"));
274 test.Next(_L("Test the conversion of powers of 2"));
275 for (exp = 0; exp < 2047; ++exp)
280 test.Next(_L("Test the conversion of powers of 10"));
281 for (exp = -325; exp < 325; ++exp)
283 DoTestPow10(exp, errors);
286 test.Next(_L("Test the conversion of some random numbers"));
287 for (exp = 0; exp < 100; ++exp)
289 DoTestRandom(errors);
292 test_Equal(0, errors);