Skip to content

Commit 705338b

Browse files
committed
[MERGE #5657 @duongnhn] Add NativeTest for BigInt class
Merge pull request #5657 from duongnhn:user/duongn/nativetest-bigint - Create first nativetests for BigInt class in DataStructure. - Cover: Init, Add, Substract. - TODO: add more for other operation.
2 parents 07271b9 + 826ea3a commit 705338b

File tree

5 files changed

+294
-11
lines changed

5 files changed

+294
-11
lines changed

bin/NativeTests/BigIntTest.cpp

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
#include "stdafx.h"
7+
#pragma warning(disable:26434) // Function definition hides non-virtual function in base class
8+
#pragma warning(disable:26439) // Implicit noexcept
9+
#pragma warning(disable:26451) // Arithmetic overflow
10+
#pragma warning(disable:26495) // Uninitialized member variable
11+
#include "catch.hpp"
12+
#include "BigIntTest.h"
13+
14+
#pragma warning(disable:4100) // unreferenced formal parameter
15+
#pragma warning(disable:6387) // suppressing preFAST which raises warning for passing null to the JsRT APIs
16+
#pragma warning(disable:6262) // CATCH is using stack variables to report errors, suppressing the preFAST warning.
17+
18+
namespace BigIntTest
19+
{
20+
TEST_CASE("Init_Compare", "[BigIntTest]")
21+
{
22+
uint32 digits[1];
23+
int32 length = 1;
24+
Js::BigInt bi1, bi2;
25+
BOOL f;
26+
int result;
27+
28+
digits[0] = 0x00001111;
29+
f = bi1.FInitFromRglu(digits, length);
30+
REQUIRE(f);
31+
32+
SECTION("Equal number init from the same array and length")
33+
{
34+
f = bi2.FInitFromRglu(digits, length);
35+
REQUIRE(f);
36+
result = bi1.Compare(&bi2);
37+
CHECK(result == 0);
38+
}
39+
40+
SECTION("Equal number init from other big int number")
41+
{
42+
f = bi2.FInitFromBigint(&bi1);
43+
REQUIRE(f);
44+
result = bi1.Compare(&bi2);
45+
CHECK(result == 0);
46+
}
47+
48+
SECTION("Greater number")
49+
{
50+
digits[0] = 0x00000001;
51+
f = bi2.FInitFromRglu(digits, length);
52+
REQUIRE(f);
53+
result = bi1.Compare(&bi2);
54+
CHECK(result == 1);
55+
}
56+
57+
SECTION("Smaller number")
58+
{
59+
digits[0] = 0x00000001;
60+
f = bi2.FInitFromRglu(digits, length);
61+
REQUIRE(f);
62+
result = bi2.Compare(&bi1);
63+
CHECK(result == -1);
64+
}
65+
}
66+
67+
TEST_CASE("Addition", "[BigIntTest]")
68+
{
69+
uint32 digits[1], digit1s[2];
70+
int32 length = 1;
71+
Js::BigInt bi1, bi2, bi3;
72+
BOOL f;
73+
int result;
74+
75+
SECTION("Check 0x33331111 + 0x33331111 = 0x66662222")
76+
{
77+
digits[0] = 0x33331111;
78+
f = bi1.FInitFromRglu(digits, length);
79+
REQUIRE(f);
80+
f = bi2.FInitFromBigint(&bi1);
81+
REQUIRE(f);
82+
f = bi1.FAdd(&bi2);
83+
REQUIRE(f);
84+
digits[0] = 0x66662222;
85+
f = bi3.FInitFromRglu(digits, length);
86+
REQUIRE(f);
87+
result = bi1.Compare(&bi3);
88+
CHECK(result == 0);
89+
}
90+
91+
SECTION("Check 0xffffffff + 0x1 = 0x100000000")
92+
{
93+
digits[0] = 0xffffffff;
94+
f = bi1.FInitFromRglu(digits, length);
95+
REQUIRE(f);
96+
digits[0] = 0x00000001;
97+
f = bi2.FInitFromRglu(digits, length);
98+
REQUIRE(f);
99+
f = bi1.FAdd(&bi2);
100+
digit1s[0] = 0x0;
101+
digit1s[1] = 0x1;
102+
f = bi3.FInitFromRglu(digit1s, 2);
103+
REQUIRE(f);
104+
result = bi1.Compare(&bi3);
105+
CHECK(result == 0);
106+
}
107+
108+
SECTION("Check 0xffffffffffffffff + 0x1 = 0x10000000000000000")
109+
{
110+
digit1s[0] = 0xffffffff;
111+
digit1s[1] = 0xffffffff;
112+
f = bi1.FInitFromRglu(digit1s, 2);
113+
REQUIRE(f);
114+
digits[0] = 0x00000001;
115+
f = bi2.FInitFromRglu(digits, 1);
116+
REQUIRE(f);
117+
f = bi1.FAdd(&bi2);
118+
uint32 digit2s[3];
119+
digit2s[0] = 0x0;
120+
digit2s[1] = 0x0;
121+
digit2s[2] = 0x1;
122+
f = bi3.FInitFromRglu(digit2s, 3);
123+
REQUIRE(f);
124+
result = bi1.Compare(&bi3);
125+
CHECK(result == 0);
126+
}
127+
}
128+
129+
TEST_CASE("Addition_Subtraction_Large_Number", "[BigIntTest]")
130+
{
131+
const int l1 = 50, l2 = 1;
132+
uint32 digit1s[l1], digit2s[l2];
133+
Js::BigInt bi1, bi2;
134+
BOOL f;
135+
136+
SECTION("Check 0xf...0xf + 0x1 = 0x1_0x0...0x0")
137+
{
138+
for (int i = 0; i < l1; i++)
139+
{
140+
digit1s[i] = 0xffffffff;
141+
}
142+
f = bi1.FInitFromRglu(digit1s, l1);
143+
REQUIRE(f);
144+
digit2s[0] = 0x1;
145+
f = bi2.FInitFromRglu(digit2s, l2);
146+
REQUIRE(f);
147+
f = bi1.FAdd(&bi2);
148+
REQUIRE(f);
149+
int32 length = bi1.Clu();
150+
CHECK(length == l1 + 1);
151+
uint32 digit = bi1.Lu(length - 1);
152+
CHECK(digit == 1);
153+
for (int i = 0; i < length - 1; i++)
154+
{
155+
digit = bi1.Lu(i);
156+
CHECK(digit == 0);
157+
}
158+
}
159+
}
160+
161+
TEST_CASE("Subtraction", "[BigIntTest]")
162+
{
163+
uint32 digits[1], digit1s[2];
164+
int32 length = 1;
165+
Js::BigInt bi1, bi2, bi3;
166+
BOOL f;
167+
int result;
168+
169+
SECTION("Check 0x66662222 - 0x33331111 = 0x33331111")
170+
{
171+
digits[0] = 0x33331111;
172+
f = bi1.FInitFromRglu(digits, length);
173+
REQUIRE(f);
174+
f = bi2.FInitFromBigint(&bi1);
175+
REQUIRE(f);
176+
digits[0] = 0x66662222;
177+
f = bi3.FInitFromRglu(digits, length);
178+
REQUIRE(f);
179+
bi3.Subtract(&bi2);
180+
result = bi1.Compare(&bi3);
181+
CHECK(result == 0);
182+
}
183+
184+
SECTION("Check 0x3_0x1 - 0x1_0x0 = 0x2_0x1")
185+
{
186+
digit1s[0] = 0x1;
187+
digit1s[1] = 0x3;
188+
f = bi3.FInitFromRglu(digit1s, 2);
189+
REQUIRE(f);
190+
digit1s[0] = 0x0;
191+
digit1s[1] = 0x1;
192+
f = bi2.FInitFromRglu(digit1s, 2);
193+
REQUIRE(f);
194+
bi3.Subtract(&bi2);
195+
int l = bi3.Clu();
196+
CHECK(l == 2);
197+
int digit = bi3.Lu(1);
198+
CHECK(digit == 2);
199+
digit = bi3.Lu(0);
200+
CHECK(digit == 1);
201+
}
202+
203+
SECTION("Check 0x2_0x0 - 0x1 = 0x1_0xfffffff")
204+
{
205+
digit1s[0] = 0x0;
206+
digit1s[1] = 0x2;
207+
f = bi3.FInitFromRglu(digit1s, 2);
208+
REQUIRE(f);
209+
digits[0] = 0x1;
210+
f = bi2.FInitFromRglu(digits, 1);
211+
REQUIRE(f);
212+
bi3.Subtract(&bi2);
213+
int l = bi3.Clu();
214+
CHECK(l == 2);
215+
int digit = bi3.Lu(1);
216+
CHECK(digit == 1);
217+
digit = bi3.Lu(0);
218+
CHECK(digit == 0xffffffff);
219+
}
220+
221+
SECTION("Currently 0x1_0x0 - 0x1 is overflow")
222+
{
223+
}
224+
}
225+
}

bin/NativeTests/BigIntTest.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// This file contains stubs needed to make BigIntTest successfully compile and link as well
7+
// as a means to emulate behavior of objects that interact with BigInt class
8+
9+
#include "..\..\lib\Common\Warnings.h"
10+
#include "..\..\lib\Common\Core\Api.cpp"
11+
#include "..\..\lib\Common\Common\NumberUtilities.cpp"
12+
13+
namespace Js
14+
{
15+
void Throw::FatalInternalError(long)
16+
{
17+
Assert(false);
18+
}
19+
20+
bool Throw::ReportAssert(__in char const *, unsigned int, __in char const *, __in char const *)
21+
{
22+
return false;
23+
}
24+
25+
void Throw::LogAssert(void) {}
26+
}
27+
28+
template <typename EncodedChar>
29+
double Js::NumberUtilities::StrToDbl(const EncodedChar *, const EncodedChar **, bool& )
30+
{
31+
Assert(false);
32+
return 0.0;// don't care
33+
}
34+
35+
#if defined(_M_IX86) || defined(_M_X64)
36+
BOOL
37+
AutoSystemInfo::SSE3Available() const
38+
{
39+
Assert(false);
40+
return TRUE;
41+
}
42+
43+
AutoSystemInfo AutoSystemInfo::Data;
44+
45+
void AutoSystemInfo::Initialize(void){}
46+
#endif
47+
48+
#include "..\..\lib\Common\DataStructures\BigInt.h"
49+
#include "..\..\lib\Common\DataStructures\BigInt.cpp"

bin/NativeTests/ConfigFlagsList.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
#pragma once
6+
7+
// stub file for ConfigFlagsList.h

bin/NativeTests/NativeTests.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<ClInclude Include="stdafx.h" />
4949
</ItemGroup>
5050
<ItemGroup>
51+
<ClCompile Include="BigIntTest.cpp" />
5152
<ClCompile Include="CodexAssert.cpp" />
5253
<ClCompile Include="CodexTests.cpp" />
5354
<ClCompile Include="FileLoadHelpers.cpp" />

lib/Common/DataStructures/BigInt.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@ namespace Js
1111
***************************************************************************/
1212
class BigInt
1313
{
14+
// Non-negative BigInt is stored as an array of 'digit' where each digit is unit32
1415
private:
1516
// Make this big enough that we rarely have to call malloc.
16-
enum { kcluMaxInit = 30 };
17+
enum { kcluMaxInit = 30 };// initilize 30 digits
1718

18-
int32 m_cluMax;
19-
int32 m_clu;
20-
uint32 *m_prglu;
21-
uint32 m_rgluInit[kcluMaxInit];
19+
int32 m_cluMax; // current maximum length (or number of digits) it can contains
20+
int32 m_clu; // current length (or number of digits)
21+
uint32 *m_prglu; // pointer to array of digits
22+
uint32 m_rgluInit[kcluMaxInit]; // pre-defined space to store array
2223

2324
inline BigInt & operator= (BigInt &bi);
24-
bool FResize(int32 clu);
25+
bool FResize(int32 clu);// allocate more space if length go over maximum
2526

2627
#if DBG
2728
#define AssertBi(pbi) Assert(pbi); (pbi)->AssertValid(true);
@@ -36,10 +37,10 @@ namespace Js
3637
BigInt(void);
3738
~BigInt(void);
3839

39-
bool FInitFromRglu(uint32 *prglu, int32 clu);
40-
bool FInitFromBigint(BigInt *pbiSrc);
40+
bool FInitFromRglu(uint32 *prglu, int32 clu); // init from array and length
41+
bool FInitFromBigint(BigInt *pbiSrc);
4142
template <typename EncodedChar>
42-
bool FInitFromDigits(const EncodedChar *prgch, int32 cch, int32 *pcchDec);
43+
bool FInitFromDigits(const EncodedChar *prgch, int32 cch, int32 *pcchDec);
4344
bool FMulAdd(uint32 luMul, uint32 luAdd);
4445
bool FMulPow5(int32 c5);
4546
bool FShiftLeft(int32 cbit);
@@ -50,8 +51,8 @@ namespace Js
5051
void Subtract(BigInt *pbi);
5152
int DivRem(BigInt *pbi);
5253

53-
int32 Clu(void);
54-
uint32 Lu(int32 ilu);
54+
int32 Clu(void); // return current length
55+
uint32 Lu(int32 ilu); // return digit at position ilu start from 0
5556
double GetDbl(void);
5657
};
5758
}

0 commit comments

Comments
 (0)