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