• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <climits>
17 
18 #include "ecmascript/js_bigint.h"
19 #include "ecmascript/tests/test_helper.h"
20 
21 using namespace panda;
22 using namespace panda::ecmascript;
23 
24 namespace panda::test {
25 class JSBigintTest : public testing::Test {
26 public:
SetUpTestCase()27     static void SetUpTestCase()
28     {
29         GTEST_LOG_(INFO) << "SetUpTestCase";
30     }
31 
TearDownTestCase()32     static void TearDownTestCase()
33     {
34         GTEST_LOG_(INFO) << "TearDownCase";
35     }
36 
SetUp()37     void SetUp() override
38     {
39         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
40     }
41 
TearDown()42     void TearDown() override
43     {
44         TestHelper::DestroyEcmaVMWithScope(instance, scope);
45     }
46 
47     EcmaVM *instance {nullptr};
48     EcmaHandleScope *scope {nullptr};
49     JSThread *thread {nullptr};
50 };
51 
52 /**
53  * @tc.name: Compare
54  * @tc.desc:
55  * @tc.type: FUNC
56  * @tc.require:
57  */
HWTEST_F_L0(JSBigintTest,Compare)58 HWTEST_F_L0(JSBigintTest, Compare)
59 {
60     CString str1 = "9007199254740991012345";
61     CString str2 = "9007199254740991012345 ";
62     CString str3 = "-9007199254740991012345";
63     CString str4 = "-9007199254740991012";
64     JSHandle<BigInt> bigint1 = BigIntHelper::SetBigInt(thread, str1);
65     JSHandle<BigInt> bigint2 = BigIntHelper::SetBigInt(thread, str2);
66     JSHandle<BigInt> bigint3 = BigIntHelper::SetBigInt(thread, str3);
67     JSHandle<BigInt> bigint4 = BigIntHelper::SetBigInt(thread, str4);
68     EXPECT_EQ(BigInt::Compare(bigint1.GetTaggedValue(), bigint1.GetTaggedValue()), ComparisonResult::EQUAL);
69     EXPECT_EQ(BigInt::Compare(bigint3.GetTaggedValue(), bigint2.GetTaggedValue()), ComparisonResult::LESS);
70     EXPECT_EQ(BigInt::Compare(bigint1.GetTaggedValue(), bigint2.GetTaggedValue()), ComparisonResult::LESS);
71     EXPECT_EQ(BigInt::Compare(bigint2.GetTaggedValue(), bigint1.GetTaggedValue()), ComparisonResult::GREAT);
72     EXPECT_EQ(BigInt::Compare(bigint2.GetTaggedValue(), bigint3.GetTaggedValue()), ComparisonResult::GREAT);
73     EXPECT_EQ(BigInt::Compare(bigint3.GetTaggedValue(), bigint4.GetTaggedValue()), ComparisonResult::LESS);
74     EXPECT_EQ(BigInt::Compare(bigint4.GetTaggedValue(), bigint3.GetTaggedValue()), ComparisonResult::GREAT);
75 
76     JSHandle<BigInt> zero = BigInt::Uint32ToBigInt(thread, 0);
77     EXPECT_EQ(BigInt::Compare(zero.GetTaggedValue(), bigint1.GetTaggedValue()), ComparisonResult::LESS);
78     EXPECT_EQ(BigInt::Compare(bigint1.GetTaggedValue(), zero.GetTaggedValue()), ComparisonResult::GREAT);
79     EXPECT_EQ(BigInt::Compare(zero.GetTaggedValue(), zero.GetTaggedValue()), ComparisonResult::EQUAL);
80     EXPECT_EQ(BigInt::Compare(zero.GetTaggedValue(), bigint3.GetTaggedValue()), ComparisonResult::GREAT);
81     EXPECT_EQ(BigInt::Compare(bigint3.GetTaggedValue(), zero.GetTaggedValue()), ComparisonResult::LESS);
82 }
83 
84 /**
85  * @tc.name: CreateBigint
86  * @tc.desc:
87  * @tc.type: FUNC
88  * @tc.require:
89  */
HWTEST_F_L0(JSBigintTest,CreateBigint)90 HWTEST_F_L0(JSBigintTest, CreateBigint)
91 {
92     uint32_t size = 100;
93     JSHandle<BigInt> bigint = BigInt::CreateBigint(thread, size);
94     EXPECT_EQ(bigint->GetLength(), size);
95 }
96 
97 /**
98  * @tc.name: Equal & SameValue & SameValueZero
99  * @tc.desc:
100  * @tc.type: FUNC
101  * @tc.require:
102  */
HWTEST_F_L0(JSBigintTest,Equal_SameValue_SameValueZero)103 HWTEST_F_L0(JSBigintTest, Equal_SameValue_SameValueZero)
104 {
105     // The largest safe integer in JavaScript is in [-(2 ^ 53 - 1), 2 ^ 53 - 1].
106     CString maxSafeIntStr = "9007199254740991";
107     CString minSafeIntStr = "-9007199254740991";
108     JSHandle<BigInt> maxSafeInt = BigIntHelper::SetBigInt(thread, maxSafeIntStr);
109     JSHandle<BigInt> minSafeInt = BigIntHelper::SetBigInt(thread, minSafeIntStr);
110 
111     // Compare two integers in the safe range.
112     JSHandle<BigInt> minusMinSafeInt = BigInt::UnaryMinus(thread, minSafeInt);
113     JSHandle<BigInt> minusMaxSafeInt = BigInt::UnaryMinus(thread, maxSafeInt);
114     bool result1 = BigInt::Equal(maxSafeInt.GetTaggedValue(), minSafeInt.GetTaggedValue());
115     bool result2 = BigInt::SameValue(maxSafeInt.GetTaggedValue(), minSafeInt.GetTaggedValue());
116     bool result3 = BigInt::SameValueZero(maxSafeInt.GetTaggedValue(), minSafeInt.GetTaggedValue());
117     EXPECT_TRUE(!result1);
118     EXPECT_TRUE(!result2);
119     EXPECT_TRUE(!result3);
120     result1 = BigInt::Equal(maxSafeInt.GetTaggedValue(), minusMinSafeInt.GetTaggedValue());
121     result2 = BigInt::SameValue(maxSafeInt.GetTaggedValue(), minusMinSafeInt.GetTaggedValue());
122     result3 = BigInt::SameValueZero(maxSafeInt.GetTaggedValue(), minusMinSafeInt.GetTaggedValue());
123     EXPECT_TRUE(result1);
124     EXPECT_TRUE(result2);
125     EXPECT_TRUE(result3);
126     result1 = BigInt::Equal(minSafeInt.GetTaggedValue(), minusMaxSafeInt.GetTaggedValue());
127     result2 = BigInt::SameValue(minSafeInt.GetTaggedValue(), minusMaxSafeInt.GetTaggedValue());
128     result3 = BigInt::SameValueZero(minSafeInt.GetTaggedValue(), minusMaxSafeInt.GetTaggedValue());
129     EXPECT_TRUE(result1);
130     EXPECT_TRUE(result2);
131     EXPECT_TRUE(result3);
132 
133     // Compare two integers outside the safe range.
134     CString unsafeIntStr1 = maxSafeIntStr + "0123456789";
135     CString unsafeIntStr2 = minSafeIntStr + "0123456789";
136     JSHandle<BigInt> unsafeInt1 = BigIntHelper::SetBigInt(thread, unsafeIntStr1);
137     JSHandle<BigInt> unsafeInt2 = BigIntHelper::SetBigInt(thread, unsafeIntStr2);
138     JSHandle<BigInt> minusUnsafeInt1 = BigInt::UnaryMinus(thread, unsafeInt1);
139     result1 = BigInt::Equal(unsafeInt2.GetTaggedValue(), minusUnsafeInt1.GetTaggedValue());
140     result2 = BigInt::SameValue(unsafeInt2.GetTaggedValue(), minusUnsafeInt1.GetTaggedValue());
141     result3 = BigInt::SameValueZero(unsafeInt2.GetTaggedValue(), minusUnsafeInt1.GetTaggedValue());
142     EXPECT_TRUE(result1);
143     EXPECT_TRUE(result2);
144     EXPECT_TRUE(result3);
145 }
146 
147 /**
148  * @tc.name: InitializationZero
149  * @tc.desc:
150  * @tc.type: FUNC
151  * @tc.require:
152  */
HWTEST_F_L0(JSBigintTest,InitializationZero)153 HWTEST_F_L0(JSBigintTest, InitializationZero)
154 {
155     CString maxSafeIntPlusOneStr = "9007199254740992";
156     JSHandle<BigInt> maxSafeIntPlusOne = BigIntHelper::SetBigInt(thread, maxSafeIntPlusOneStr);
157     uint32_t size = maxSafeIntPlusOne->GetLength();
158     uint32_t countZero = 0;
159     for (uint32_t i = 0; i < size; i++) {
160         uint32_t digit = maxSafeIntPlusOne->GetDigit(i);
161         if (digit == 0) {
162             countZero++;
163         }
164     }
165     EXPECT_NE(countZero, size);
166 
167     maxSafeIntPlusOne->InitializationZero();
168     for (uint32_t i = 0; i < size; i++) {
169         uint32_t digit = maxSafeIntPlusOne->GetDigit(i);
170         EXPECT_EQ(digit, 0U);
171     }
172 }
173 
174 /**
175  * @tc.name: BitwiseOp & BitwiseAND & BitwiseXOR & BitwiseOR & BitwiseSubOne & BitwiseAddOne & BitwiseNOT
176  * @tc.desc:
177  * @tc.type: FUNC
178  * @tc.require:
179  */
HWTEST_F_L0(JSBigintTest,Bitwise_AND_XOR_OR_NOT_SubOne_AddOne)180 HWTEST_F_L0(JSBigintTest, Bitwise_AND_XOR_OR_NOT_SubOne_AddOne)
181 {
182     CString maxSafeIntStr = "11111111111111111111111111111111111111111111111111111"; // Binary: 2 ^ 53 - 1
183     CString maxSafeIntPlusOneStr = "100000000000000000000000000000000000000000000000000000"; // Binary: 2 ^ 53
184     CString bigintStr1 = "111111111111111111111111111111111111111111111111111111"; // Binary: 2 ^ 54 - 1
185     CString bigintStr2 = "11011100";
186     JSHandle<BigInt> maxSafeInt = BigIntHelper::SetBigInt(thread, maxSafeIntStr, BigInt::BINARY);
187     JSHandle<BigInt> maxSafeIntPlusOne = BigIntHelper::SetBigInt(thread, maxSafeIntPlusOneStr, BigInt::BINARY);
188     JSHandle<BigInt> bigint1 = BigIntHelper::SetBigInt(thread, bigintStr1, BigInt::BINARY);
189     JSHandle<BigInt> bigint2 = BigIntHelper::SetBigInt(thread, bigintStr2, BigInt::BINARY);
190     JSHandle<BigInt> bigint3 = BigInt::UnaryMinus(thread, bigint2);
191     JSHandle<BigInt> bigint4 = BigInt::UnaryMinus(thread, bigint1);
192     // Bitwise AND operation
193     JSHandle<BigInt> addOpRes = BigInt::BitwiseOp(thread, Operate::AND, maxSafeIntPlusOne, bigint1);
194     JSHandle<BigInt> andRes = BigInt::BitwiseAND(thread, maxSafeIntPlusOne, bigint1);
195     EXPECT_TRUE(BigInt::Equal(addOpRes.GetTaggedValue(), maxSafeIntPlusOne.GetTaggedValue()));
196     EXPECT_TRUE(BigInt::Equal(andRes.GetTaggedValue(), maxSafeIntPlusOne.GetTaggedValue()));
197 
198     JSHandle<BigInt> addOpRes1 = BigInt::BitwiseOp(thread, Operate::AND, bigint1, bigint2);
199     JSHandle<BigInt> andRes1 = BigInt::BitwiseAND(thread, bigint1, bigint2);
200     EXPECT_TRUE(BigInt::Equal(addOpRes1.GetTaggedValue(), bigint2.GetTaggedValue()));
201     EXPECT_TRUE(BigInt::Equal(andRes1.GetTaggedValue(), bigint2.GetTaggedValue()));
202 
203     JSHandle<BigInt> addOpRes2 = BigInt::BitwiseOp(thread, Operate::AND, bigint2, bigint1);
204     JSHandle<BigInt> andRes2 = BigInt::BitwiseAND(thread, bigint2, bigint1);
205     EXPECT_TRUE(BigInt::Equal(addOpRes2.GetTaggedValue(), bigint2.GetTaggedValue()));
206     EXPECT_TRUE(BigInt::Equal(andRes2.GetTaggedValue(), bigint2.GetTaggedValue()));
207 
208     CString bigintStr4 = "111111111111111111111111111111111111111111111100100100";
209     JSHandle<BigInt> bigint = BigIntHelper::SetBigInt(thread, bigintStr4, BigInt::BINARY);
210     JSHandle<BigInt> andRes3 = BigInt::BitwiseAND(thread, bigint3, bigint1);
211     EXPECT_TRUE(BigInt::Equal(andRes3.GetTaggedValue(), bigint.GetTaggedValue()));
212 
213     JSHandle<BigInt> andRes4 = BigInt::BitwiseAND(thread, bigint1, bigint3);
214     EXPECT_TRUE(BigInt::Equal(andRes4.GetTaggedValue(), bigint.GetTaggedValue()));
215 
216     CString bigintStr5 = "-1000000000000000000000000000000000000000000000000000000";
217     JSHandle<BigInt> bigint5 = BigIntHelper::SetBigInt(thread, bigintStr5, BigInt::BINARY);
218     JSHandle<BigInt> andRes5 = BigInt::BitwiseAND(thread, bigint3, bigint4);
219     EXPECT_TRUE(BigInt::Equal(andRes5.GetTaggedValue(), bigint5.GetTaggedValue()));
220 
221     CString bigintStr6 = "-1000000000000000000000000000000000000000000000000000000";
222     JSHandle<BigInt> bigint6 = BigIntHelper::SetBigInt(thread, bigintStr6, BigInt::BINARY);
223     JSHandle<BigInt> andRes6 = BigInt::BitwiseAND(thread, bigint4, bigint3);
224     EXPECT_TRUE(BigInt::Equal(andRes6.GetTaggedValue(), bigint6.GetTaggedValue()));
225 
226     // Bitwise OR operation
227     JSHandle<BigInt> orOpRes = BigInt::BitwiseOp(thread, Operate::OR, maxSafeInt, maxSafeIntPlusOne);
228     JSHandle<BigInt> orRes = BigInt::BitwiseOR(thread, maxSafeInt, maxSafeIntPlusOne);
229     EXPECT_TRUE(BigInt::Equal(orOpRes.GetTaggedValue(), bigint1.GetTaggedValue()));
230     EXPECT_TRUE(BigInt::Equal(orRes.GetTaggedValue(), bigint1.GetTaggedValue()));
231 
232     JSHandle<BigInt> orRes1 = BigInt::BitwiseOR(thread, bigint3, maxSafeIntPlusOne);
233     EXPECT_TRUE(BigInt::Equal(orRes1.GetTaggedValue(), bigint3.GetTaggedValue()));
234 
235     JSHandle<BigInt> orRes2 = BigInt::BitwiseOR(thread, maxSafeIntPlusOne, bigint3);
236     EXPECT_TRUE(BigInt::Equal(orRes2.GetTaggedValue(), bigint3.GetTaggedValue()));
237 
238     CString bigintStr7 = "-11011011";
239     JSHandle<BigInt> bigint7 = BigIntHelper::SetBigInt(thread, bigintStr7, BigInt::BINARY);
240     JSHandle<BigInt> orRes3 = BigInt::BitwiseOR(thread, bigint3, bigint4);
241     EXPECT_TRUE(BigInt::Equal(orRes3.GetTaggedValue(), bigint7.GetTaggedValue()));
242 
243     // Bitwise XOR operation
244     JSHandle<BigInt> xorOpRes = BigInt::BitwiseOp(thread, Operate::XOR, maxSafeIntPlusOne, bigint1);
245     JSHandle<BigInt> xorRes = BigInt::BitwiseXOR(thread, maxSafeIntPlusOne, bigint1);
246     EXPECT_TRUE(BigInt::Equal(xorOpRes.GetTaggedValue(), maxSafeInt.GetTaggedValue()));
247     EXPECT_TRUE(BigInt::Equal(xorRes.GetTaggedValue(), maxSafeInt.GetTaggedValue()));
248 
249     CString bigintStr8 = "-100000000000000000000000000000000000000000000011011100";
250     JSHandle<BigInt> bigint8 = BigIntHelper::SetBigInt(thread, bigintStr8, BigInt::BINARY);
251     JSHandle<BigInt> xorRes1 = BigInt::BitwiseXOR(thread, bigint3, maxSafeIntPlusOne);
252     EXPECT_TRUE(BigInt::Equal(xorRes1.GetTaggedValue(), bigint8.GetTaggedValue()));
253 
254     JSHandle<BigInt> xorRes2 = BigInt::BitwiseXOR(thread, maxSafeIntPlusOne, bigint3);
255     EXPECT_TRUE(BigInt::Equal(xorRes2.GetTaggedValue(), bigint8.GetTaggedValue()));
256 
257     CString bigintStr9 = "111111111111111111111111111111111111111111111100100101";
258     JSHandle<BigInt> bigint9 = BigIntHelper::SetBigInt(thread, bigintStr9, BigInt::BINARY);
259     JSHandle<BigInt> xorRes3 = BigInt::BitwiseXOR(thread, bigint3, bigint4);
260     EXPECT_TRUE(BigInt::Equal(xorRes3.GetTaggedValue(), bigint9.GetTaggedValue()));
261 
262     // Bitwise NOT operation, include sign bits.
263     JSHandle<BigInt> notRes1 = BigInt::BitwiseNOT(thread, maxSafeInt);
264     JSHandle<BigInt> minusMaxSafeInt = BigInt::UnaryMinus(thread, maxSafeIntPlusOne);
265     // ~x == -x-1 == -(x+1)
266     EXPECT_TRUE(BigInt::Equal(notRes1.GetTaggedValue(), minusMaxSafeInt.GetTaggedValue()));
267     JSHandle<BigInt> notRes2 = BigInt::BitwiseNOT(thread, minusMaxSafeInt);
268     // ~(-x) == ~(~(x-1)) == x-1
269     EXPECT_TRUE(BigInt::Equal(notRes2.GetTaggedValue(), maxSafeInt.GetTaggedValue()));
270 
271     // Bitwise sub one operation, include sign bits.
272     uint32_t maxSize = maxSafeIntPlusOne->GetLength();
273     JSHandle<BigInt> subOneRes = BigInt::BitwiseSubOne(thread, maxSafeIntPlusOne, maxSize);
274     EXPECT_TRUE(BigInt::Equal(subOneRes.GetTaggedValue(), maxSafeInt.GetTaggedValue()));
275 
276     // Bitwise add one operation, include sign bits.
277     JSHandle<BigInt> addOneRes = BigInt::BitwiseAddOne(thread, maxSafeInt);
278     JSHandle<BigInt> minusMaxSafePlusOneInt = BigInt::UnaryMinus(thread, maxSafeIntPlusOne);
279     EXPECT_TRUE(BigInt::Equal(addOneRes.GetTaggedValue(), minusMaxSafePlusOneInt.GetTaggedValue()));
280 
281     JSHandle<BigInt> newBigint = BigInt::CreateBigint(thread, 2);
282     newBigint->SetDigit(0, std::numeric_limits<uint32_t>::max());
283     newBigint->SetDigit(1, std::numeric_limits<uint32_t>::max());
284     JSHandle<BigInt> addOneRes1 = BigInt::BitwiseAddOne(thread, newBigint);
285     addOneRes1->SetSign(false);
286     JSHandle<BigInt> newBigint1 = BigInt::CreateBigint(thread, 3);
287     newBigint1->SetDigit(0, 0);
288     newBigint1->SetDigit(1, 0);
289     newBigint1->SetDigit(2, 1);
290     EXPECT_TRUE(BigInt::Equal(addOneRes1.GetTaggedValue(), newBigint1.GetTaggedValue()));
291 }
292 
293 /**
294  * @tc.name: ToString & ToStdString
295  * @tc.desc:
296  * @tc.type: FUNC
297  * @tc.require:
298  */
HWTEST_F_L0(JSBigintTest,ToString_ToStdString)299 HWTEST_F_L0(JSBigintTest, ToString_ToStdString)
300 {
301     CString bigintStdStr1 = "111111111111111111111111111111111111111111111111111111"; // Binary: 2 ^ 54 - 1
302     CString bigintStdStr2 = "1234567890987654321"; // Decimal
303     JSHandle<BigInt> bigint1 = BigIntHelper::SetBigInt(thread, bigintStdStr1, BigInt::BINARY);
304     JSHandle<BigInt> bigint2 = BigIntHelper::SetBigInt(thread, bigintStdStr2, BigInt::DECIMAL);
305 
306     JSHandle<EcmaString> bigintEcmaStrBin1 = BigInt::ToString(thread, bigint1, BigInt::BINARY);
307     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrBin1).ToCString().c_str(),
308         "111111111111111111111111111111111111111111111111111111");
309     JSHandle<EcmaString> bigintEcmaStrOct1 = BigInt::ToString(thread, bigint1, BigInt::OCTAL);
310     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrOct1).ToCString().c_str(), "777777777777777777");
311     JSHandle<EcmaString> bigintEcmaStrDec1 = BigInt::ToString(thread, bigint1, BigInt::DECIMAL);
312     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrDec1).ToCString().c_str(), "18014398509481983");
313     JSHandle<EcmaString> bigintEcmaStrHex1 = BigInt::ToString(thread, bigint1, BigInt::HEXADECIMAL);
314     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrHex1).ToCString().c_str(), "3fffffffffffff");
315 
316     JSHandle<EcmaString> bigintEcmaStrBin2 = BigInt::ToString(thread, bigint2, BigInt::BINARY);
317     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrBin2).ToCString().c_str(),
318         "1000100100010000100001111010010110001011011000001110010110001");
319     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrBin2).ToCString().c_str(),
320         (bigint2->ToStdString(BigInt::BINARY)).c_str());
321 
322     JSHandle<EcmaString> bigintEcmaStrOct2 = BigInt::ToString(thread, bigint2, BigInt::OCTAL);
323     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrOct2).ToCString().c_str(), "104420417226133016261");
324     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrOct2).ToCString().c_str(),
325         (bigint2->ToStdString(BigInt::OCTAL)).c_str());
326 
327     JSHandle<EcmaString> bigintEcmaStrDec2 = BigInt::ToString(thread, bigint2, BigInt::DECIMAL);
328     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrDec2).ToCString().c_str(), "1234567890987654321");
329     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrDec2).ToCString().c_str(),
330         (bigint2->ToStdString(BigInt::DECIMAL)).c_str());
331 
332     JSHandle<EcmaString> bigintEcmaStrHex2 = BigInt::ToString(thread, bigint2, BigInt::HEXADECIMAL);
333     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrHex2).ToCString().c_str(), "112210f4b16c1cb1");
334     EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrHex2).ToCString().c_str(),
335         (bigint2->ToStdString(BigInt::HEXADECIMAL)).c_str());
336 }
337 
338 /**
339  * @tc.name: UnaryMinus
340  * @tc.desc:
341  * @tc.type: FUNC
342  * @tc.require:
343  */
HWTEST_F_L0(JSBigintTest,UnaryMinus)344 HWTEST_F_L0(JSBigintTest, UnaryMinus)
345 {
346     CString maxSafeIntStr = "9007199254740991";
347     CString minSafeIntStr = "-9007199254740991";
348     CString maxSafeIntPlusOneStr = "9007199254740992";
349     CString minSafeIntSubOneStr = "-9007199254740992";
350     JSHandle<BigInt> maxSafeInt = BigIntHelper::SetBigInt(thread, maxSafeIntStr);
351     JSHandle<BigInt> minSafeInt = BigIntHelper::SetBigInt(thread, minSafeIntStr);
352     JSHandle<BigInt> maxSafeIntPlusOne = BigIntHelper::SetBigInt(thread, maxSafeIntPlusOneStr);
353     JSHandle<BigInt> minSafeIntSubOne = BigIntHelper::SetBigInt(thread, minSafeIntSubOneStr);
354 
355     JSHandle<BigInt> minusRes1 = BigInt::UnaryMinus(thread, maxSafeInt);
356     EXPECT_TRUE(BigInt::Equal(minusRes1.GetTaggedValue(), minSafeInt.GetTaggedValue()));
357     JSHandle<BigInt> minusRes2 = BigInt::UnaryMinus(thread, minSafeInt);
358     EXPECT_TRUE(BigInt::Equal(minusRes2.GetTaggedValue(), maxSafeInt.GetTaggedValue()));
359     JSHandle<BigInt> minusRes3 = BigInt::UnaryMinus(thread, maxSafeIntPlusOne);
360     EXPECT_TRUE(BigInt::Equal(minusRes3.GetTaggedValue(), minSafeIntSubOne.GetTaggedValue()));
361     JSHandle<BigInt> minusRes4 = BigInt::UnaryMinus(thread, minSafeIntSubOne);
362     EXPECT_TRUE(BigInt::Equal(minusRes4.GetTaggedValue(), maxSafeIntPlusOne.GetTaggedValue()));
363 
364     JSHandle<BigInt> zero = BigInt::Int32ToBigInt(thread, 0);
365     JSHandle<BigInt> minusRes5 = BigInt::UnaryMinus(thread, zero);
366     EXPECT_TRUE(!minusRes5->GetSign());
367     EXPECT_TRUE(BigInt::Equal(zero.GetTaggedValue(), minusRes5.GetTaggedValue()));
368 }
369 
370 /**
371  * @tc.name: Exponentiate & Multiply & Divide & Remainder
372  * @tc.desc:
373  * @tc.type: FUNC
374  * @tc.require:
375  */
HWTEST_F_L0(JSBigintTest,Exponentiate_Multiply_Divide_Remainder)376 HWTEST_F_L0(JSBigintTest, Exponentiate_Multiply_Divide_Remainder)
377 {
378     CString baseBigintStr = "2";
379     CString expBigintStr1 = "53";
380     CString expBigintStr2 = "54";
381     CString resBigintStr1 = "9007199254740992"; // 2 ^ 53
382     CString resBigintStr2 = "18014398509481984"; // 2 ^ 54
383     CString resBigintStr3 = "162259276829213363391578010288128"; // 2 ^ 107
384     CString resBigintStr4 = "162259276829213363391578010288182"; // 2 ^ 107 + 54
385     JSHandle<BigInt> baseBigint = BigIntHelper::SetBigInt(thread, baseBigintStr);
386     JSHandle<BigInt> expBigint1 = BigIntHelper::SetBigInt(thread, expBigintStr1);
387     JSHandle<BigInt> expBigint2 = BigIntHelper::SetBigInt(thread, expBigintStr2);
388     JSHandle<BigInt> resBigint1 = BigIntHelper::SetBigInt(thread, resBigintStr1);
389     JSHandle<BigInt> resBigint2 = BigIntHelper::SetBigInt(thread, resBigintStr2);
390     JSHandle<BigInt> resBigint3 = BigIntHelper::SetBigInt(thread, resBigintStr3);
391     JSHandle<BigInt> resBigint4 = BigIntHelper::SetBigInt(thread, resBigintStr4);
392     JSHandle<BigInt> resBigint5 = BigInt::Int32ToBigInt(thread, -1);
393     JSHandle<BigInt> zero = BigInt::Int32ToBigInt(thread, 0);
394     // Exponentiate
395     JSHandle<BigInt> expRes1 = BigInt::Exponentiate(thread, baseBigint, expBigint1);
396     EXPECT_TRUE(BigInt::Equal(expRes1.GetTaggedValue(), resBigint1.GetTaggedValue()));
397     JSHandle<BigInt> expRes2 = BigInt::Exponentiate(thread, baseBigint, expBigint2);
398     EXPECT_TRUE(BigInt::Equal(expRes2.GetTaggedValue(), resBigint2.GetTaggedValue()));
399     JSHandle<BigInt> expRes3 = BigInt::Exponentiate(thread, baseBigint, resBigint5);
400     EXPECT_TRUE(expRes3.GetTaggedValue().IsException());
401     thread->ClearException();
402     // Multiply
403     JSHandle<BigInt> mulRes1 = BigInt::Multiply(thread, baseBigint, baseBigint);
404     for (int32_t i = 0; i < atoi(expBigintStr1.c_str()) - 2; i++) {
405         mulRes1 = BigInt::Multiply(thread, mulRes1, baseBigint);
406     }
407     EXPECT_TRUE(BigInt::Equal(mulRes1.GetTaggedValue(), resBigint1.GetTaggedValue()));
408     JSHandle<BigInt> mulRes2 = BigInt::Multiply(thread, baseBigint, baseBigint);
409     for (int32_t i = 0; i < atoi(expBigintStr2.c_str()) - 2; i++) {
410         mulRes2 = BigInt::Multiply(thread, mulRes2, baseBigint);
411     }
412     EXPECT_TRUE(BigInt::Equal(mulRes2.GetTaggedValue(), resBigint2.GetTaggedValue()));
413     JSHandle<BigInt> mulRes3 = BigInt::Multiply(thread, resBigint1, resBigint2);
414     EXPECT_TRUE(BigInt::Equal(mulRes3.GetTaggedValue(), resBigint3.GetTaggedValue()));
415 
416     // Divide
417     // The result has no remainder.
418     JSHandle<BigInt> divRes1 = BigInt::Divide(thread, resBigint3, resBigint2);
419     EXPECT_TRUE(BigInt::Equal(divRes1.GetTaggedValue(), resBigint1.GetTaggedValue()));
420     JSHandle<BigInt> divRes2 = BigInt::Divide(thread, resBigint3, resBigint1);
421     EXPECT_TRUE(BigInt::Equal(divRes2.GetTaggedValue(), resBigint2.GetTaggedValue()));
422     // The result has a remainder.
423     JSHandle<BigInt> divRes3 = BigInt::Divide(thread, resBigint4, resBigint1);
424     EXPECT_TRUE(BigInt::Equal(divRes3.GetTaggedValue(), resBigint2.GetTaggedValue()));
425     JSHandle<BigInt> divRes4 = BigInt::Divide(thread, resBigint4, resBigint2);
426     EXPECT_TRUE(BigInt::Equal(divRes4.GetTaggedValue(), resBigint1.GetTaggedValue()));
427     JSHandle<BigInt> divRes5 = BigInt::Divide(thread, baseBigint, zero);
428     EXPECT_TRUE(divRes5.GetTaggedValue().IsException());
429     thread->ClearException();
430     JSHandle<BigInt> divRes6 = BigInt::Divide(thread, expBigint2, baseBigint);
431     JSHandle<BigInt> expectRes6 = BigInt::Int32ToBigInt(thread, 27); // 27 : Expected calculation results
432     EXPECT_TRUE(BigInt::Equal(divRes6.GetTaggedValue(), expectRes6.GetTaggedValue()));
433     JSHandle<BigInt> divRes7 = BigInt::Divide(thread, expBigint1, baseBigint);
434     JSHandle<BigInt> expectRes7 = BigInt::Int32ToBigInt(thread, 26); // 26 : Expected calculation results
435     EXPECT_TRUE(BigInt::Equal(divRes7.GetTaggedValue(), expectRes7.GetTaggedValue()));
436 
437     // Remainder
438     JSHandle<BigInt> remRes1 = BigInt::Remainder(thread, resBigint4, resBigint1);
439     EXPECT_TRUE(BigInt::Equal(remRes1.GetTaggedValue(), expBigint2.GetTaggedValue()));
440     JSHandle<BigInt> remRes2 = BigInt::Remainder(thread, resBigint4, resBigint2);
441     EXPECT_TRUE(BigInt::Equal(remRes2.GetTaggedValue(), expBigint2.GetTaggedValue()));
442     JSHandle<BigInt> remRes3 = BigInt::Remainder(thread, resBigint4, resBigint3);
443     EXPECT_TRUE(BigInt::Equal(remRes3.GetTaggedValue(), expBigint2.GetTaggedValue()));
444     JSHandle<BigInt> remRes4 = BigInt::Remainder(thread, baseBigint, zero);
445     EXPECT_TRUE(remRes4.GetTaggedValue().IsException());
446     thread->ClearException();
447     JSHandle<BigInt> remRes5 = BigInt::Remainder(thread, expBigint2, baseBigint);
448     EXPECT_TRUE(BigInt::Equal(remRes5.GetTaggedValue(), zero.GetTaggedValue()));
449     JSHandle<BigInt> remRes6 = BigInt::Remainder(thread, expBigint1, baseBigint);
450     JSHandle<BigInt> expect = BigInt::Int32ToBigInt(thread, 1);
451     EXPECT_TRUE(BigInt::Equal(remRes6.GetTaggedValue(), expect.GetTaggedValue()));
452 }
453 
454 /**
455  * @tc.name: ToInt64
456  * @tc.desc:
457  * @tc.type: FUNC
458  * @tc.require:
459  */
HWTEST_F_L0(JSBigintTest,ToInt64)460 HWTEST_F_L0(JSBigintTest, ToInt64)
461 {
462     CString resBigintStr1 = std::to_string(LLONG_MAX).c_str();
463     CString resBigintStr2 = std::to_string(LLONG_MIN).c_str();
464     CString resBigintStr3 = std::to_string(INT_MAX).c_str();
465     CString resBigintStr4 = std::to_string(INT_MIN).c_str();
466     CString resBigintStr5 = "0";
467 
468     JSHandle<BigInt> resBigint1 = BigIntHelper::SetBigInt(thread, resBigintStr1);
469     JSHandle<BigInt> resBigint2 = BigIntHelper::SetBigInt(thread, resBigintStr2);
470     JSHandle<BigInt> resBigint3 = BigIntHelper::SetBigInt(thread, resBigintStr3);
471     JSHandle<BigInt> resBigint4 = BigIntHelper::SetBigInt(thread, resBigintStr4);
472     JSHandle<BigInt> resBigint5 = BigIntHelper::SetBigInt(thread, resBigintStr5);
473 
474     EXPECT_TRUE(resBigint1->ToInt64() == LLONG_MAX);
475     EXPECT_TRUE(resBigint2->ToInt64() == LLONG_MIN);
476     EXPECT_TRUE(resBigint3->ToInt64() == INT_MAX);
477     EXPECT_TRUE(resBigint4->ToInt64() == INT_MIN);
478     EXPECT_TRUE(resBigint5->ToInt64() == 0);
479 }
480 
481 /**
482  * @tc.name: ToUint64
483  * @tc.desc:
484  * @tc.type: FUNC
485  * @tc.require:
486  */
HWTEST_F_L0(JSBigintTest,ToUint64)487 HWTEST_F_L0(JSBigintTest, ToUint64)
488 {
489     CString resBigintStr1 = std::to_string(ULLONG_MAX).c_str();
490     CString resBigintStr2 = std::to_string(UINT_MAX).c_str();
491     CString resBigintStr3 = "0";
492 
493     JSHandle<BigInt> resBigint1 = BigIntHelper::SetBigInt(thread, resBigintStr1);
494     JSHandle<BigInt> resBigint2 = BigIntHelper::SetBigInt(thread, resBigintStr2);
495     JSHandle<BigInt> resBigint3 = BigIntHelper::SetBigInt(thread, resBigintStr3);
496 
497     EXPECT_TRUE(resBigint1->ToUint64() == ULLONG_MAX);
498     EXPECT_TRUE(resBigint2->ToUint64() == UINT_MAX);
499     EXPECT_TRUE(resBigint3->ToUint64() == 0);
500 }
501 
502 /**
503  * @tc.name: Int64ToBigInt
504  * @tc.desc:
505  * @tc.type: FUNC
506  * @tc.require:
507  */
HWTEST_F_L0(JSBigintTest,Int64ToBigInt)508 HWTEST_F_L0(JSBigintTest, Int64ToBigInt)
509 {
510     // JSHandle<BigInt> BigInt::Int64ToBigInt(JSThread *thread, const int64_t &number)
511     JSHandle<BigInt> resBigint1 = BigInt::Int64ToBigInt(thread, LLONG_MAX);
512     JSHandle<BigInt> resBigint2 = BigInt::Int64ToBigInt(thread, LLONG_MIN);
513     JSHandle<BigInt> resBigint3 = BigInt::Int64ToBigInt(thread, INT_MAX);
514     JSHandle<BigInt> resBigint4 = BigInt::Int64ToBigInt(thread, INT_MIN);
515     JSHandle<BigInt> resBigint5 = BigInt::Int64ToBigInt(thread, 0);
516 
517     EXPECT_TRUE(resBigint1->ToInt64() == LLONG_MAX);
518     EXPECT_TRUE(resBigint2->ToInt64() == LLONG_MIN);
519     EXPECT_TRUE(resBigint3->ToInt64() == INT_MAX);
520     EXPECT_TRUE(resBigint4->ToInt64() == INT_MIN);
521     EXPECT_TRUE(resBigint5->ToInt64() == 0);
522 }
523 
524 /**
525  * @tc.name: Uint64ToBigInt
526  * @tc.desc:
527  * @tc.type: FUNC
528  * @tc.require:
529  */
HWTEST_F_L0(JSBigintTest,Uint64ToBigInt)530 HWTEST_F_L0(JSBigintTest, Uint64ToBigInt)
531 {
532     JSHandle<BigInt> resBigint1 = BigInt::Uint64ToBigInt(thread, ULLONG_MAX);
533     JSHandle<BigInt> resBigint2 = BigInt::Uint64ToBigInt(thread, UINT_MAX);
534     JSHandle<BigInt> resBigint3 = BigInt::Uint64ToBigInt(thread, 0);
535 
536     EXPECT_TRUE(resBigint1->ToUint64() == ULLONG_MAX);
537     EXPECT_TRUE(resBigint2->ToUint64() == UINT_MAX);
538     EXPECT_TRUE(resBigint3->ToUint64() == 0);
539 }
540 
GetWordsArray(bool * signBit,size_t wordCount,uint64_t * words,JSHandle<BigInt> bigintVal)541 void GetWordsArray(bool *signBit, size_t wordCount, uint64_t *words, JSHandle<BigInt> bigintVal)
542 {
543     uint32_t len = bigintVal->GetLength();
544     uint32_t count = 0;
545     uint32_t index = 0;
546     for (; index < wordCount - 1; ++index) {
547         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
548         words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
549     }
550     if (len % 2 == 0) { // 2 : len is odd or even
551         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
552         words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
553     } else {
554         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
555     }
556     *signBit = bigintVal->GetSign();
557 }
558 
559 /**
560  * @tc.name: CreateBigWords
561  * @tc.desc:
562  * @tc.type: FUNC
563  * @tc.require:
564  */
HWTEST_F_L0(JSBigintTest,CreateBigWords)565 HWTEST_F_L0(JSBigintTest, CreateBigWords)
566 {
567     size_t wordCount = 4;
568     uint64_t words[] = { 0xFFFFFFFFFFFFFFFF, 34ULL, 56ULL, 0xFFFFFFFFFFFFFFFF };
569     JSHandle<BigInt> bigintFalse = BigInt::CreateBigWords(thread, false, wordCount, words);
570     bool sign = true;
571     uint64_t wordsOut[] = { 0ULL, 0ULL, 0ULL, 0ULL };
572     GetWordsArray(&sign, wordCount, wordsOut, bigintFalse);
573     EXPECT_TRUE(sign == false);
574     for (size_t i = 0; i < wordCount; i++) {
575         EXPECT_TRUE(words[i] == wordsOut[i]);
576     }
577 
578     JSHandle<BigInt> bigintTrue = BigInt::CreateBigWords(thread, true, wordCount, words);
579     GetWordsArray(&sign, wordCount, wordsOut, bigintTrue);
580     EXPECT_TRUE(sign == true);
581     for (size_t i = 0; i < wordCount; i++) {
582         EXPECT_TRUE(words[i] == wordsOut[i]);
583     }
584 
585     size_t wordCount1 = 5;
586     uint64_t words1[] = { 12ULL, 34ULL, 56ULL, 78ULL, 90ULL };
587     JSHandle<BigInt> bigintFalse1 = BigInt::CreateBigWords(thread, false, wordCount1, words1);
588 
589     bool sign1 = true;
590     uint64_t wordsOut1[] = { 0ULL, 0ULL, 0ULL, 0ULL, 0ULL };
591     GetWordsArray(&sign1, wordCount1, wordsOut1, bigintFalse1);
592     EXPECT_TRUE(sign1 == false);
593     for (size_t i = 0; i < wordCount1; i++) {
594         EXPECT_TRUE(words1[i] == wordsOut1[i]);
595     }
596 
597     size_t wordCount2 = 0;
598     uint64_t words2[10] = { 0 };
599     JSHandle<BigInt> bigint1 = BigInt::CreateBigWords(thread, true, wordCount2, words2);
600     EXPECT_TRUE(bigint1->IsZero());
601 
602     BigInt::CreateBigWords(thread, true, INT_MAX, words2);
603     EXPECT_TRUE(thread->HasPendingException());
604     thread->ClearException();
605 }
606 
607 /**
608  * @tc.name: GetUint64MaxBigint GetInt64MaxBigint
609  * @tc.desc:
610  * @tc.type: FUNC
611  * @tc.require:
612  */
HWTEST_F_L0(JSBigintTest,GetUint64MaxBigint_GetInt64MaxBigint)613 HWTEST_F_L0(JSBigintTest, GetUint64MaxBigint_GetInt64MaxBigint)
614 {
615     JSHandle<BigInt> exponent = BigInt::Int32ToBigInt(thread, 64); // 64 : bits
616     JSHandle<BigInt> exponentone = BigInt::Int32ToBigInt(thread, 63); // 63 : bits
617     JSHandle<BigInt> base = BigInt::Int32ToBigInt(thread, 2); // 2 : base value
618     JSHandle<BigInt> uint64MaxBigint1 = BigInt::Exponentiate(thread, base, exponent);
619     JSHandle<BigInt> uint64MaxBigint2 = BigInt::GetUint64MaxBigint(thread);
620     EXPECT_TRUE(BigInt::Equal(uint64MaxBigint1.GetTaggedValue(), uint64MaxBigint2.GetTaggedValue()));
621     JSHandle<BigInt> int64MaxBigint1 = BigInt::Exponentiate(thread, base, exponentone);
622     JSHandle<BigInt> int64MaxBigint2 = BigInt::GetInt64MaxBigint(thread);
623     EXPECT_TRUE(BigInt::Equal(int64MaxBigint1.GetTaggedValue(), int64MaxBigint2.GetTaggedValue()));
624 }
625 
626 /**
627  * @tc.name: Int32ToBigInt
628  * @tc.desc:
629  * @tc.type: FUNC
630  * @tc.require:
631  */
HWTEST_F_L0(JSBigintTest,Int32ToBigInt)632 HWTEST_F_L0(JSBigintTest, Int32ToBigInt)
633 {
634     JSHandle<BigInt> resBigint1 = BigInt::Int32ToBigInt(thread, std::numeric_limits<int32_t>::max());
635     JSHandle<BigInt> resBigint2 = BigInt::Int32ToBigInt(thread, std::numeric_limits<int32_t>::min());
636     JSHandle<BigInt> resBigint3 = BigInt::Int32ToBigInt(thread, 0);
637 
638     EXPECT_TRUE(static_cast<int32_t>(resBigint1->GetDigit(0)) == std::numeric_limits<int32_t>::max());
639     EXPECT_FALSE(resBigint1->GetSign());
640     EXPECT_TRUE(static_cast<int32_t>(resBigint2->GetDigit(0)) == std::numeric_limits<int32_t>::min());
641     EXPECT_TRUE(resBigint2->GetSign());
642     EXPECT_TRUE(static_cast<int32_t>(resBigint3->GetDigit(0)) == 0);
643     EXPECT_FALSE(resBigint3->GetSign());
644 }
645 
646 /**
647  * @tc.name: Uint32ToBigInt
648  * @tc.desc:
649  * @tc.type: FUNC
650  * @tc.require:
651  */
HWTEST_F_L0(JSBigintTest,Uint32ToBigInt)652 HWTEST_F_L0(JSBigintTest, Uint32ToBigInt)
653 {
654     JSHandle<BigInt> resBigint1 = BigInt::Uint32ToBigInt(thread, std::numeric_limits<uint32_t>::max());
655     JSHandle<BigInt> resBigint2 = BigInt::Uint32ToBigInt(thread, std::numeric_limits<uint32_t>::min());
656     JSHandle<BigInt> resBigint3 = BigInt::Uint32ToBigInt(thread, 0);
657 
658     EXPECT_TRUE(resBigint1->GetDigit(0) == std::numeric_limits<uint32_t>::max());
659     EXPECT_FALSE(resBigint1->GetSign());
660     EXPECT_TRUE(resBigint2->GetDigit(0) == std::numeric_limits<uint32_t>::min());
661     EXPECT_FALSE(resBigint2->GetSign());
662     EXPECT_TRUE(resBigint3->GetDigit(0) == 0);
663     EXPECT_FALSE(resBigint3->GetSign());
664 }
665 
666 /**
667  * @tc.name: BigIntToInt64
668  * @tc.desc:
669  * @tc.type: FUNC
670  * @tc.require:
671  */
HWTEST_F_L0(JSBigintTest,BigIntToInt64)672 HWTEST_F_L0(JSBigintTest, BigIntToInt64)
673 {
674     JSHandle<BigInt> resBigint1 = BigInt::Int64ToBigInt(thread, LLONG_MAX);
675     JSHandle<BigInt> resBigint2 = BigInt::Int64ToBigInt(thread, LLONG_MIN);
676     JSHandle<BigInt> resBigint3 = BigInt::Int64ToBigInt(thread, INT_MAX);
677     JSHandle<BigInt> resBigint4 = BigInt::Int64ToBigInt(thread, INT_MIN);
678     JSHandle<BigInt> resBigint5 = BigInt::Int64ToBigInt(thread, 0);
679     int64_t cValue = 0;
680     bool lossless = false;
681     BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint1), &cValue, &lossless);
682     EXPECT_TRUE(cValue == LLONG_MAX);
683     EXPECT_TRUE(lossless);
684     BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint2), &cValue, &lossless);
685     EXPECT_TRUE(cValue == LLONG_MIN);
686     EXPECT_TRUE(lossless);
687     BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint3), &cValue, &lossless);
688     EXPECT_TRUE(cValue == INT_MAX);
689     EXPECT_TRUE(lossless);
690     BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint4), &cValue, &lossless);
691     EXPECT_TRUE(cValue == INT_MIN);
692     EXPECT_TRUE(lossless);
693     BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint5), &cValue, &lossless);
694     EXPECT_TRUE(cValue == 0);
695     EXPECT_TRUE(lossless);
696 
697     JSHandle<BigInt> resBigint6 = BigInt::CreateBigint(thread, 3); // 3 : bigint length
698     resBigint6->SetDigit(0, 0);
699     resBigint6->SetDigit(1, 0);
700     resBigint6->SetDigit(2, 1); // 2 : index
701     lossless = false;
702     BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint6), &cValue, &lossless);
703     EXPECT_TRUE(cValue == 0);
704     EXPECT_TRUE(!lossless);
705 
706     resBigint6->SetSign(true);
707     resBigint6->SetDigit(2, 2); // 2 : index
708     BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint6), &cValue, &lossless);
709     EXPECT_TRUE(cValue == 0);
710     EXPECT_TRUE(!lossless);
711 }
712 
713 /**
714  * @tc.name: BigIntToUint64
715  * @tc.desc:
716  * @tc.type: FUNC
717  * @tc.require:
718  */
HWTEST_F_L0(JSBigintTest,BigIntToUint64)719 HWTEST_F_L0(JSBigintTest, BigIntToUint64)
720 {
721     JSHandle<BigInt> resBigint1 = BigInt::Uint64ToBigInt(thread, ULLONG_MAX);
722     JSHandle<BigInt> resBigint2 = BigInt::Uint64ToBigInt(thread, UINT_MAX);
723     JSHandle<BigInt> resBigint3 = BigInt::Uint64ToBigInt(thread, 0);
724 
725     uint64_t cValue = 0;
726     bool lossless = false;
727     BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint1), &cValue, &lossless);
728     EXPECT_TRUE(cValue == ULLONG_MAX);
729     EXPECT_TRUE(lossless);
730     BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint2), &cValue, &lossless);
731     EXPECT_TRUE(cValue == UINT_MAX);
732     EXPECT_TRUE(lossless);
733     BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint3), &cValue, &lossless);
734     EXPECT_TRUE(cValue == 0);
735     EXPECT_TRUE(lossless);
736 
737     JSHandle<BigInt> resBigint4 = BigInt::CreateBigint(thread, 3); // 3 : bigint length
738     resBigint4->SetDigit(0, 0);
739     resBigint4->SetDigit(1, 0);
740     resBigint4->SetDigit(2, 1); // 2 : index
741     lossless = false;
742     BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint4), &cValue, &lossless);
743     EXPECT_TRUE(cValue == 0);
744     EXPECT_TRUE(!lossless);
745 }
746 
747 /**
748  * @tc.name: Add
749  * @tc.desc:
750  * @tc.type: FUNC
751  * @tc.require:
752  */
HWTEST_F_L0(JSBigintTest,Add)753 HWTEST_F_L0(JSBigintTest, Add)
754 {
755     JSHandle<BigInt> resBigint = BigInt::CreateBigint(thread, 2); // 2 : bigint length
756     resBigint->SetDigit(0, 0);
757     resBigint->SetDigit(1, 1);
758     resBigint->SetSign(true);
759     JSHandle<BigInt> resBigint1 = BigInt::CreateBigint(thread, 2); // 2 : bigint length
760     resBigint1->SetDigit(0, 1);
761     resBigint1->SetDigit(1, 1);
762 
763     JSHandle<BigInt> addres = BigInt::Add(thread, resBigint, resBigint1);
764     EXPECT_TRUE(addres->GetLength() == 1);
765     EXPECT_TRUE(addres->GetDigit(0) == 1);
766     JSHandle<BigInt> addres1 = BigInt::Add(thread, resBigint1, resBigint);
767     EXPECT_TRUE(addres1->GetLength() == 1);
768     EXPECT_TRUE(addres1->GetDigit(0) == 1);
769 
770     JSHandle<BigInt> resBigint2 = BigInt::Int32ToBigInt(thread, 1);
771     JSHandle<BigInt> addres2 = BigInt::Add(thread, resBigint2, resBigint);
772     EXPECT_TRUE(addres2->GetLength() == 1);
773     EXPECT_TRUE(addres2->GetSign());
774     EXPECT_TRUE(addres2->GetDigit(0) == std::numeric_limits<uint32_t>::max());
775 
776     JSHandle<BigInt> addres3 = BigInt::Add(thread, resBigint2, resBigint1);
777     EXPECT_TRUE(addres3->GetLength() == 2); // 2 : bigint length
778     EXPECT_TRUE(!addres3->GetSign());
779     EXPECT_TRUE(addres3->GetDigit(0) == 2); // 2 : digit value
780 }
781 
782 /**
783  * @tc.name: Subtract
784  * @tc.desc:
785  * @tc.type: FUNC
786  * @tc.require:
787  */
HWTEST_F_L0(JSBigintTest,Subtract)788 HWTEST_F_L0(JSBigintTest, Subtract)
789 {
790     JSHandle<BigInt> resBigint = BigInt::CreateBigint(thread, 2); // 2 : bigint length
791     resBigint->SetDigit(0, 0);
792     resBigint->SetDigit(1, 1);
793     JSHandle<BigInt> resBigint1 = BigInt::CreateBigint(thread, 2); // 2 : bigint length
794     resBigint1->SetDigit(0, 1);
795     resBigint1->SetDigit(1, 1);
796 
797     JSHandle<BigInt> addres = BigInt::Subtract(thread, resBigint1, resBigint);
798     EXPECT_TRUE(addres->GetLength() == 1);
799     EXPECT_TRUE(addres->GetDigit(0) == 1);
800     JSHandle<BigInt> addres1 = BigInt::Subtract(thread, resBigint1, resBigint);
801     EXPECT_TRUE(addres1->GetLength() == 1);
802     EXPECT_TRUE(addres1->GetDigit(0) == 1);
803 
804     JSHandle<BigInt> resBigint2 = BigInt::Int32ToBigInt(thread, -1);
805     EXPECT_TRUE(resBigint2->GetSign());
806     JSHandle<BigInt> addres2 = BigInt::Subtract(thread, resBigint, resBigint2);
807     EXPECT_TRUE(BigInt::Equal(addres2.GetTaggedValue(), resBigint1.GetTaggedValue()));
808 }
809 
810 /**
811  * @tc.name: BigintSubOne
812  * @tc.desc:
813  * @tc.type: FUNC
814  * @tc.require:
815  */
HWTEST_F_L0(JSBigintTest,BigintSubOne)816 HWTEST_F_L0(JSBigintTest, BigintSubOne)
817 {
818     JSHandle<BigInt> resBigint = BigInt::Int32ToBigInt(thread, -1);
819     EXPECT_TRUE(resBigint->GetSign());
820     JSHandle<BigInt> addres = BigInt::BigintSubOne(thread, resBigint);
821     EXPECT_TRUE(addres->GetSign());
822     EXPECT_TRUE(addres->GetDigit(0) == 2);
823 
824     JSHandle<BigInt> resBigint1 = BigInt::Int32ToBigInt(thread, 1);
825     JSHandle<BigInt> addres1 = BigInt::BigintSubOne(thread, resBigint1);
826     EXPECT_TRUE(addres1->GetDigit(0) == 0);
827 }
828 
829 /**
830  * @tc.name: SignedRightShift
831  * @tc.desc:
832  * @tc.type: FUNC
833  * @tc.require:
834  */
HWTEST_F_L0(JSBigintTest,SignedRightShift)835 HWTEST_F_L0(JSBigintTest, SignedRightShift)
836 {
837     // the left operand is a positive number
838     CString bigintStr1 = "111111011011110111111101111111101111111111110111111111110111111011";
839     JSHandle<BigInt> bigint1 = BigIntHelper::SetBigInt(thread, bigintStr1, BigInt::BINARY);
840     JSHandle<BigInt> shift1 = BigInt::Int32ToBigInt(thread, 20); // 20 : shiftBits
841     JSHandle<BigInt> res1 = BigInt::SignedRightShift(thread, bigint1, shift1);
842 
843     CString expectResStr1 = "1111110110111101111111011111111011111111111101";
844     JSHandle<BigInt> expectRes1 = BigIntHelper::SetBigInt(thread, expectResStr1, BigInt::BINARY);
845     EXPECT_TRUE(BigInt::Equal(res1.GetTaggedValue(), expectRes1.GetTaggedValue()));
846 
847     JSHandle<BigInt> shift2 = BigInt::Int32ToBigInt(thread, 0);
848     JSHandle<BigInt> res2 = BigInt::SignedRightShift(thread, bigint1, shift2);
849     EXPECT_TRUE(BigInt::Equal(res2.GetTaggedValue(), bigint1.GetTaggedValue()));
850 
851     JSHandle<BigInt> res3 = BigInt::SignedRightShift(thread, shift2, bigint1);
852     EXPECT_TRUE(BigInt::Equal(res3.GetTaggedValue(), shift2.GetTaggedValue()));
853 
854     JSHandle<BigInt> shift3 = BigInt::Int32ToBigInt(thread, -33); // -33 : shiftBits
855     JSHandle<BigInt> res4 = BigInt::SignedRightShift(thread, bigint1, shift3);
856     CString expectResStr4 =
857         "111111011011110111111101111111101111111111110111111111110111111011000000000000000000000000000000000";
858     JSHandle<BigInt> expectRes4 = BigIntHelper::SetBigInt(thread, expectResStr4, BigInt::BINARY);
859     EXPECT_TRUE(BigInt::Equal(res4.GetTaggedValue(), expectRes4.GetTaggedValue()));
860 
861     // left operand is negative number
862     JSHandle<BigInt> bigint2 = BigInt::UnaryMinus(thread, bigint1);
863 
864     CString expectResStr5 =
865         "-1111110110111101111111011111111011111111111110";
866     JSHandle<BigInt> expectRes5 = BigIntHelper::SetBigInt(thread, expectResStr5, BigInt::BINARY);
867     JSHandle<BigInt> res5 = BigInt::SignedRightShift(thread, bigint2, shift1);
868     EXPECT_TRUE(BigInt::Equal(res5.GetTaggedValue(), expectRes5.GetTaggedValue()));
869 
870     CString expectResStr6 =
871         "-111111011011110111111101111111101111111111110111111111110111111011000000000000000000000000000000000";
872     JSHandle<BigInt> expectRes6 = BigIntHelper::SetBigInt(thread, expectResStr6, BigInt::BINARY);
873     JSHandle<BigInt> res6 = BigInt::SignedRightShift(thread, bigint2, shift3);
874     EXPECT_TRUE(BigInt::Equal(res6.GetTaggedValue(), expectRes6.GetTaggedValue()));
875 
876     JSHandle<BigInt> res7 = BigInt::SignedRightShift(thread, shift3, bigint1);
877     JSHandle<BigInt> expectRes7 = BigInt::Int32ToBigInt(thread, -1);
878     EXPECT_TRUE(BigInt::Equal(res7.GetTaggedValue(), expectRes7.GetTaggedValue()));
879 
880     JSHandle<BigInt> shift4 = BigInt::Int32ToBigInt(thread, 65); // 65 : shiftBits
881     JSHandle<BigInt> res8 = BigInt::SignedRightShift(thread, shift3, shift4);
882     EXPECT_TRUE(BigInt::Equal(res8.GetTaggedValue(), expectRes7.GetTaggedValue()));
883 }
884 
885 /**
886  * @tc.name: LeftShift
887  * @tc.desc:
888  * @tc.type: FUNC
889  * @tc.require:
890  */
HWTEST_F_L0(JSBigintTest,LeftShift)891 HWTEST_F_L0(JSBigintTest, LeftShift)
892 {
893     // the left operand is a positive number
894     CString bigintStr1 = "111111011011110111111101111111101111111111110111111111110111111011";
895     JSHandle<BigInt> bigint1 = BigIntHelper::SetBigInt(thread, bigintStr1, BigInt::BINARY);
896     JSHandle<BigInt> shift1 = BigInt::Int32ToBigInt(thread, 20); // 20 : shiftBits
897     JSHandle<BigInt> res1 = BigInt::LeftShift(thread, bigint1, shift1);
898 
899     CString expectResStr1 =
900         "11111101101111011111110111111110111111111111011111111111011111101100000000000000000000";
901     JSHandle<BigInt> expectRes1 = BigIntHelper::SetBigInt(thread, expectResStr1, BigInt::BINARY);
902     EXPECT_TRUE(BigInt::Equal(res1.GetTaggedValue(), expectRes1.GetTaggedValue()));
903 
904     JSHandle<BigInt> shift2 = BigInt::Int32ToBigInt(thread, 0);
905     JSHandle<BigInt> res2 = BigInt::LeftShift(thread, bigint1, shift2);
906     EXPECT_TRUE(BigInt::Equal(res2.GetTaggedValue(), bigint1.GetTaggedValue()));
907 
908     JSHandle<BigInt> shift3 = BigInt::Int32ToBigInt(thread, -33); // -33 : shiftBits
909     JSHandle<BigInt> res4 = BigInt::LeftShift(thread, bigint1, shift3);
910     CString expectResStr4 = "111111011011110111111101111111101";
911     JSHandle<BigInt> expectRes4 = BigIntHelper::SetBigInt(thread, expectResStr4, BigInt::BINARY);
912     EXPECT_TRUE(BigInt::Equal(res4.GetTaggedValue(), expectRes4.GetTaggedValue()));
913 
914     // left operand is negative number
915     JSHandle<BigInt> bigint2 = BigInt::UnaryMinus(thread, bigint1);
916 
917     CString expectResStr5 =
918         "-11111101101111011111110111111110111111111111011111111111011111101100000000000000000000";
919     JSHandle<BigInt> expectRes5 = BigIntHelper::SetBigInt(thread, expectResStr5, BigInt::BINARY);
920     JSHandle<BigInt> res5 = BigInt::LeftShift(thread, bigint2, shift1);
921     EXPECT_TRUE(BigInt::Equal(res5.GetTaggedValue(), expectRes5.GetTaggedValue()));
922 
923     CString expectResStr6 = "-111111011011110111111101111111110";
924     JSHandle<BigInt> expectRes6 = BigIntHelper::SetBigInt(thread, expectResStr6, BigInt::BINARY);
925     JSHandle<BigInt> res6 = BigInt::LeftShift(thread, bigint2, shift3);
926     EXPECT_TRUE(BigInt::Equal(res6.GetTaggedValue(), expectRes6.GetTaggedValue()));
927 }
928 
929 } // namespace panda::test