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 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().c_str(),
284 "111111111111111111111111111111111111111111111111111111");
285 JSHandle<EcmaString> bigintEcmaStrOct1 = BigInt::ToString(thread, bigint1, BigInt::OCTAL);
286 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrOct1).ToCString().c_str(), "777777777777777777");
287 JSHandle<EcmaString> bigintEcmaStrDec1 = BigInt::ToString(thread, bigint1, BigInt::DECIMAL);
288 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrDec1).ToCString().c_str(), "18014398509481983");
289 JSHandle<EcmaString> bigintEcmaStrHex1 = BigInt::ToString(thread, bigint1, BigInt::HEXADECIMAL);
290 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrHex1).ToCString().c_str(), "3fffffffffffff");
291
292 JSHandle<EcmaString> bigintEcmaStrBin2 = BigInt::ToString(thread, bigint2, BigInt::BINARY);
293 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrBin2).ToCString().c_str(),
294 "1000100100010000100001111010010110001011011000001110010110001");
295 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrBin2).ToCString().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().c_str(), "104420417226133016261");
300 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrOct2).ToCString().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().c_str(), "1234567890987654321");
305 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrDec2).ToCString().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().c_str(), "112210f4b16c1cb1");
310 EXPECT_STREQ(EcmaStringAccessor(bigintEcmaStrHex2).ToCString().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
493 EXPECT_TRUE(resBigint1->ToInt64() == LLONG_MAX);
494 EXPECT_TRUE(resBigint2->ToInt64() == LLONG_MIN);
495 EXPECT_TRUE(resBigint3->ToInt64() == INT_MAX);
496 EXPECT_TRUE(resBigint4->ToInt64() == INT_MIN);
497 EXPECT_TRUE(resBigint5->ToInt64() == 0);
498 }
499
500 /**
501 * @tc.name: Uint64ToBigInt
502 * @tc.desc:
503 * @tc.type: FUNC
504 * @tc.require:
505 */
HWTEST_F_L0(JSBigintTest,Uint64ToBigInt)506 HWTEST_F_L0(JSBigintTest, Uint64ToBigInt)
507 {
508 JSHandle<BigInt> resBigint1 = BigInt::Uint64ToBigInt(thread, ULLONG_MAX);
509 JSHandle<BigInt> resBigint2 = BigInt::Uint64ToBigInt(thread, UINT_MAX);
510 JSHandle<BigInt> resBigint3 = BigInt::Uint64ToBigInt(thread, 0);
511
512 EXPECT_TRUE(resBigint1->ToUint64() == ULLONG_MAX);
513 EXPECT_TRUE(resBigint2->ToUint64() == UINT_MAX);
514 EXPECT_TRUE(resBigint3->ToUint64() == 0);
515 }
516
GetWordsArray(bool * signBit,size_t wordCount,uint64_t * words,JSHandle<BigInt> bigintVal)517 void GetWordsArray(bool *signBit, size_t wordCount, uint64_t *words, JSHandle<BigInt> bigintVal)
518 {
519 uint32_t len = bigintVal->GetLength();
520 uint32_t count = 0;
521 uint32_t index = 0;
522 for (; index < wordCount - 1; ++index) {
523 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
524 words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
525 }
526 if (len % 2 == 0) { // 2 : len is odd or even
527 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
528 words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
529 } else {
530 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
531 }
532 *signBit = bigintVal->GetSign();
533 }
534
535 /**
536 * @tc.name: CreateBigWords
537 * @tc.desc:
538 * @tc.type: FUNC
539 * @tc.require:
540 */
HWTEST_F_L0(JSBigintTest,CreateBigWords)541 HWTEST_F_L0(JSBigintTest, CreateBigWords)
542 {
543 size_t wordCount = 4;
544 uint64_t words[] = { 0xFFFFFFFFFFFFFFFF, 34ULL, 56ULL, 0xFFFFFFFFFFFFFFFF };
545 JSHandle<BigInt> bigintFalse = BigInt::CreateBigWords(thread, false, wordCount, words);
546 bool sign = true;
547 uint64_t wordsOut[] = { 0ULL, 0ULL, 0ULL, 0ULL };
548 GetWordsArray(&sign, wordCount, wordsOut, bigintFalse);
549 EXPECT_TRUE(sign == false);
550 for (size_t i = 0; i < wordCount; i++) {
551 EXPECT_TRUE(words[i] == wordsOut[i]);
552 }
553
554 JSHandle<BigInt> bigintTrue = BigInt::CreateBigWords(thread, true, wordCount, words);
555 GetWordsArray(&sign, wordCount, wordsOut, bigintTrue);
556 EXPECT_TRUE(sign == true);
557 for (size_t i = 0; i < wordCount; i++) {
558 EXPECT_TRUE(words[i] == wordsOut[i]);
559 }
560
561 size_t wordCount1 = 5;
562 uint64_t words1[] = { 12ULL, 34ULL, 56ULL, 78ULL, 90ULL };
563 JSHandle<BigInt> bigintFalse1 = BigInt::CreateBigWords(thread, false, wordCount1, words1);
564
565 bool sign1 = true;
566 uint64_t wordsOut1[] = { 0ULL, 0ULL, 0ULL, 0ULL, 0ULL };
567 GetWordsArray(&sign1, wordCount1, wordsOut1, bigintFalse1);
568 EXPECT_TRUE(sign1 == false);
569 for (size_t i = 0; i < wordCount1; i++) {
570 EXPECT_TRUE(words1[i] == wordsOut1[i]);
571 }
572
573 size_t wordCount2 = 0;
574 uint64_t words2[10] = { 0 };
575 JSHandle<BigInt> bigint1 = BigInt::CreateBigWords(thread, true, wordCount2, words2);
576 EXPECT_TRUE(bigint1->IsZero());
577
578 BigInt::CreateBigWords(thread, true, INT_MAX, words2);
579 EXPECT_TRUE(thread->HasPendingException());
580 thread->ClearException();
581 }
582
583 /**
584 * @tc.name: GetUint64MaxBigInt GetInt64MaxBigInt
585 * @tc.desc:
586 * @tc.type: FUNC
587 * @tc.require:
588 */
HWTEST_F_L0(JSBigintTest,GetUint64MaxBigint_GetInt64MaxBigint)589 HWTEST_F_L0(JSBigintTest, GetUint64MaxBigint_GetInt64MaxBigint)
590 {
591 JSHandle<BigInt> exponent = BigInt::Int32ToBigInt(thread, 64); // 64 : bits
592 JSHandle<BigInt> exponentone = BigInt::Int32ToBigInt(thread, 63); // 63 : bits
593 JSHandle<BigInt> base = BigInt::Int32ToBigInt(thread, 2); // 2 : base value
594 JSHandle<BigInt> uint64MaxBigint1 = BigInt::Exponentiate(thread, base, exponent);
595 JSHandle<BigInt> uint64MaxBigint2 = BigInt::GetUint64MaxBigInt(thread);
596 EXPECT_TRUE(BigInt::Equal(uint64MaxBigint1.GetTaggedValue(), uint64MaxBigint2.GetTaggedValue()));
597 JSHandle<BigInt> int64MaxBigint1 = BigInt::Exponentiate(thread, base, exponentone);
598 JSHandle<BigInt> int64MaxBigint2 = BigInt::GetInt64MaxBigInt(thread);
599 EXPECT_TRUE(BigInt::Equal(int64MaxBigint1.GetTaggedValue(), int64MaxBigint2.GetTaggedValue()));
600 }
601
602 /**
603 * @tc.name: Int32ToBigInt
604 * @tc.desc:
605 * @tc.type: FUNC
606 * @tc.require:
607 */
HWTEST_F_L0(JSBigintTest,Int32ToBigInt)608 HWTEST_F_L0(JSBigintTest, Int32ToBigInt)
609 {
610 JSHandle<BigInt> resBigint1 = BigInt::Int32ToBigInt(thread, std::numeric_limits<int32_t>::max());
611 JSHandle<BigInt> resBigint2 = BigInt::Int32ToBigInt(thread, std::numeric_limits<int32_t>::min());
612 JSHandle<BigInt> resBigint3 = BigInt::Int32ToBigInt(thread, 0);
613
614 EXPECT_TRUE(static_cast<int32_t>(resBigint1->GetDigit(0)) == std::numeric_limits<int32_t>::max());
615 EXPECT_FALSE(resBigint1->GetSign());
616 EXPECT_TRUE(static_cast<int32_t>(resBigint2->GetDigit(0)) == std::numeric_limits<int32_t>::min());
617 EXPECT_TRUE(resBigint2->GetSign());
618 EXPECT_TRUE(static_cast<int32_t>(resBigint3->GetDigit(0)) == 0);
619 EXPECT_FALSE(resBigint3->GetSign());
620 }
621
622 /**
623 * @tc.name: Uint32ToBigInt
624 * @tc.desc:
625 * @tc.type: FUNC
626 * @tc.require:
627 */
HWTEST_F_L0(JSBigintTest,Uint32ToBigInt)628 HWTEST_F_L0(JSBigintTest, Uint32ToBigInt)
629 {
630 JSHandle<BigInt> resBigint1 = BigInt::Uint32ToBigInt(thread, std::numeric_limits<uint32_t>::max());
631 JSHandle<BigInt> resBigint2 = BigInt::Uint32ToBigInt(thread, std::numeric_limits<uint32_t>::min());
632 JSHandle<BigInt> resBigint3 = BigInt::Uint32ToBigInt(thread, 0);
633
634 EXPECT_TRUE(resBigint1->GetDigit(0) == std::numeric_limits<uint32_t>::max());
635 EXPECT_FALSE(resBigint1->GetSign());
636 EXPECT_TRUE(resBigint2->GetDigit(0) == std::numeric_limits<uint32_t>::min());
637 EXPECT_FALSE(resBigint2->GetSign());
638 EXPECT_TRUE(resBigint3->GetDigit(0) == 0);
639 EXPECT_FALSE(resBigint3->GetSign());
640 }
641
642 /**
643 * @tc.name: BigIntToInt64
644 * @tc.desc:
645 * @tc.type: FUNC
646 * @tc.require:
647 */
HWTEST_F_L0(JSBigintTest,BigIntToInt64)648 HWTEST_F_L0(JSBigintTest, BigIntToInt64)
649 {
650 JSHandle<BigInt> resBigint1 = BigInt::Int64ToBigInt(thread, LLONG_MAX);
651 JSHandle<BigInt> resBigint2 = BigInt::Int64ToBigInt(thread, LLONG_MIN);
652 JSHandle<BigInt> resBigint3 = BigInt::Int64ToBigInt(thread, INT_MAX);
653 JSHandle<BigInt> resBigint4 = BigInt::Int64ToBigInt(thread, INT_MIN);
654 JSHandle<BigInt> resBigint5 = BigInt::Int64ToBigInt(thread, 0);
655 int64_t cValue = 0;
656 bool lossless = false;
657 BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint1), &cValue, &lossless);
658 EXPECT_TRUE(cValue == LLONG_MAX);
659 EXPECT_TRUE(lossless);
660 BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint2), &cValue, &lossless);
661 EXPECT_TRUE(cValue == LLONG_MIN);
662 EXPECT_TRUE(lossless);
663 BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint3), &cValue, &lossless);
664 EXPECT_TRUE(cValue == INT_MAX);
665 EXPECT_TRUE(lossless);
666 BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint4), &cValue, &lossless);
667 EXPECT_TRUE(cValue == INT_MIN);
668 EXPECT_TRUE(lossless);
669 BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint5), &cValue, &lossless);
670 EXPECT_TRUE(cValue == 0);
671 EXPECT_TRUE(lossless);
672
673 JSHandle<BigInt> resBigint6 = BigInt::CreateBigint(thread, 3); // 3 : bigint length
674 resBigint6->SetDigit(0, 0);
675 resBigint6->SetDigit(1, 0);
676 resBigint6->SetDigit(2, 1); // 2 : index
677 lossless = false;
678 BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint6), &cValue, &lossless);
679 EXPECT_TRUE(cValue == 0);
680 EXPECT_TRUE(!lossless);
681
682 resBigint6->SetSign(true);
683 resBigint6->SetDigit(2, 2); // 2 : index
684 BigInt::BigIntToInt64(thread, JSHandle<JSTaggedValue>(resBigint6), &cValue, &lossless);
685 EXPECT_TRUE(cValue == 0);
686 EXPECT_TRUE(!lossless);
687 }
688
689 /**
690 * @tc.name: BigIntToUint64
691 * @tc.desc:
692 * @tc.type: FUNC
693 * @tc.require:
694 */
HWTEST_F_L0(JSBigintTest,BigIntToUint64)695 HWTEST_F_L0(JSBigintTest, BigIntToUint64)
696 {
697 JSHandle<BigInt> resBigint1 = BigInt::Uint64ToBigInt(thread, ULLONG_MAX);
698 JSHandle<BigInt> resBigint2 = BigInt::Uint64ToBigInt(thread, UINT_MAX);
699 JSHandle<BigInt> resBigint3 = BigInt::Uint64ToBigInt(thread, 0);
700
701 uint64_t cValue = 0;
702 bool lossless = false;
703 BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint1), &cValue, &lossless);
704 EXPECT_TRUE(cValue == ULLONG_MAX);
705 EXPECT_TRUE(lossless);
706 BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint2), &cValue, &lossless);
707 EXPECT_TRUE(cValue == UINT_MAX);
708 EXPECT_TRUE(lossless);
709 BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint3), &cValue, &lossless);
710 EXPECT_TRUE(cValue == 0);
711 EXPECT_TRUE(lossless);
712
713 JSHandle<BigInt> resBigint4 = BigInt::CreateBigint(thread, 3); // 3 : bigint length
714 resBigint4->SetDigit(0, 0);
715 resBigint4->SetDigit(1, 0);
716 resBigint4->SetDigit(2, 1); // 2 : index
717 lossless = false;
718 BigInt::BigIntToUint64(thread, JSHandle<JSTaggedValue>(resBigint4), &cValue, &lossless);
719 EXPECT_TRUE(cValue == 0);
720 EXPECT_TRUE(!lossless);
721 }
722
723 /**
724 * @tc.name: Add
725 * @tc.desc:
726 * @tc.type: FUNC
727 * @tc.require:
728 */
HWTEST_F_L0(JSBigintTest,Add)729 HWTEST_F_L0(JSBigintTest, Add)
730 {
731 JSHandle<BigInt> resBigint = BigInt::CreateBigint(thread, 2); // 2 : bigint length
732 resBigint->SetDigit(0, 0);
733 resBigint->SetDigit(1, 1);
734 resBigint->SetSign(true);
735 JSHandle<BigInt> resBigint1 = BigInt::CreateBigint(thread, 2); // 2 : bigint length
736 resBigint1->SetDigit(0, 1);
737 resBigint1->SetDigit(1, 1);
738
739 JSHandle<BigInt> addres = BigInt::Add(thread, resBigint, resBigint1);
740 EXPECT_TRUE(addres->GetLength() == 1);
741 EXPECT_TRUE(addres->GetDigit(0) == 1);
742 JSHandle<BigInt> addres1 = BigInt::Add(thread, resBigint1, resBigint);
743 EXPECT_TRUE(addres1->GetLength() == 1);
744 EXPECT_TRUE(addres1->GetDigit(0) == 1);
745
746 JSHandle<BigInt> resBigint2 = BigInt::Int32ToBigInt(thread, 1);
747 JSHandle<BigInt> addres2 = BigInt::Add(thread, resBigint2, resBigint);
748 EXPECT_TRUE(addres2->GetLength() == 1);
749 EXPECT_TRUE(addres2->GetSign());
750 EXPECT_TRUE(addres2->GetDigit(0) == std::numeric_limits<uint32_t>::max());
751
752 JSHandle<BigInt> addres3 = BigInt::Add(thread, resBigint2, resBigint1);
753 EXPECT_TRUE(addres3->GetLength() == 2); // 2 : bigint length
754 EXPECT_TRUE(!addres3->GetSign());
755 EXPECT_TRUE(addres3->GetDigit(0) == 2); // 2 : digit value
756 }
757
758 /**
759 * @tc.name: Subtract
760 * @tc.desc:
761 * @tc.type: FUNC
762 * @tc.require:
763 */
HWTEST_F_L0(JSBigintTest,Subtract)764 HWTEST_F_L0(JSBigintTest, Subtract)
765 {
766 JSHandle<BigInt> resBigint = BigInt::CreateBigint(thread, 2); // 2 : bigint length
767 resBigint->SetDigit(0, 0);
768 resBigint->SetDigit(1, 1);
769 JSHandle<BigInt> resBigint1 = BigInt::CreateBigint(thread, 2); // 2 : bigint length
770 resBigint1->SetDigit(0, 1);
771 resBigint1->SetDigit(1, 1);
772
773 JSHandle<BigInt> addres = BigInt::Subtract(thread, resBigint1, resBigint);
774 EXPECT_TRUE(addres->GetLength() == 1);
775 EXPECT_TRUE(addres->GetDigit(0) == 1);
776 JSHandle<BigInt> addres1 = BigInt::Subtract(thread, resBigint1, resBigint);
777 EXPECT_TRUE(addres1->GetLength() == 1);
778 EXPECT_TRUE(addres1->GetDigit(0) == 1);
779
780 JSHandle<BigInt> resBigint2 = BigInt::Int32ToBigInt(thread, -1);
781 EXPECT_TRUE(resBigint2->GetSign());
782 JSHandle<BigInt> addres2 = BigInt::Subtract(thread, resBigint, resBigint2);
783 EXPECT_TRUE(BigInt::Equal(addres2.GetTaggedValue(), resBigint1.GetTaggedValue()));
784 }
785
786 /**
787 * @tc.name: BigintSubOne
788 * @tc.desc:
789 * @tc.type: FUNC
790 * @tc.require:
791 */
HWTEST_F_L0(JSBigintTest,BigintSubOne)792 HWTEST_F_L0(JSBigintTest, BigintSubOne)
793 {
794 JSHandle<BigInt> resBigint = BigInt::Int32ToBigInt(thread, -1);
795 EXPECT_TRUE(resBigint->GetSign());
796 JSHandle<BigInt> addres = BigInt::BigintSubOne(thread, resBigint);
797 EXPECT_TRUE(addres->GetSign());
798 EXPECT_TRUE(addres->GetDigit(0) == 2);
799
800 JSHandle<BigInt> resBigint1 = BigInt::Int32ToBigInt(thread, 1);
801 JSHandle<BigInt> addres1 = BigInt::BigintSubOne(thread, resBigint1);
802 EXPECT_TRUE(addres1->GetDigit(0) == 0);
803 }
804
805 /**
806 * @tc.name: SignedRightShift
807 * @tc.desc:
808 * @tc.type: FUNC
809 * @tc.require:
810 */
HWTEST_F_L0(JSBigintTest,SignedRightShift)811 HWTEST_F_L0(JSBigintTest, SignedRightShift)
812 {
813 // the left operand is a positive number
814 CString bigintStr1 = "111111011011110111111101111111101111111111110111111111110111111011";
815 JSHandle<BigInt> bigint1 = BigIntHelper::SetBigInt(thread, bigintStr1, BigInt::BINARY);
816 JSHandle<BigInt> shift1 = BigInt::Int32ToBigInt(thread, 20); // 20 : shiftBits
817 JSHandle<BigInt> res1 = BigInt::SignedRightShift(thread, bigint1, shift1);
818
819 CString expectResStr1 = "1111110110111101111111011111111011111111111101";
820 JSHandle<BigInt> expectRes1 = BigIntHelper::SetBigInt(thread, expectResStr1, BigInt::BINARY);
821 EXPECT_TRUE(BigInt::Equal(res1.GetTaggedValue(), expectRes1.GetTaggedValue()));
822
823 JSHandle<BigInt> shift2 = BigInt::Int32ToBigInt(thread, 0);
824 JSHandle<BigInt> res2 = BigInt::SignedRightShift(thread, bigint1, shift2);
825 EXPECT_TRUE(BigInt::Equal(res2.GetTaggedValue(), bigint1.GetTaggedValue()));
826
827 JSHandle<BigInt> res3 = BigInt::SignedRightShift(thread, shift2, bigint1);
828 EXPECT_TRUE(BigInt::Equal(res3.GetTaggedValue(), shift2.GetTaggedValue()));
829
830 JSHandle<BigInt> shift3 = BigInt::Int32ToBigInt(thread, -33); // -33 : shiftBits
831 JSHandle<BigInt> res4 = BigInt::SignedRightShift(thread, bigint1, shift3);
832 CString expectResStr4 =
833 "111111011011110111111101111111101111111111110111111111110111111011000000000000000000000000000000000";
834 JSHandle<BigInt> expectRes4 = BigIntHelper::SetBigInt(thread, expectResStr4, BigInt::BINARY);
835 EXPECT_TRUE(BigInt::Equal(res4.GetTaggedValue(), expectRes4.GetTaggedValue()));
836
837 // left operand is negative number
838 JSHandle<BigInt> bigint2 = BigInt::UnaryMinus(thread, bigint1);
839
840 CString expectResStr5 =
841 "-1111110110111101111111011111111011111111111110";
842 JSHandle<BigInt> expectRes5 = BigIntHelper::SetBigInt(thread, expectResStr5, BigInt::BINARY);
843 JSHandle<BigInt> res5 = BigInt::SignedRightShift(thread, bigint2, shift1);
844 EXPECT_TRUE(BigInt::Equal(res5.GetTaggedValue(), expectRes5.GetTaggedValue()));
845
846 CString expectResStr6 =
847 "-111111011011110111111101111111101111111111110111111111110111111011000000000000000000000000000000000";
848 JSHandle<BigInt> expectRes6 = BigIntHelper::SetBigInt(thread, expectResStr6, BigInt::BINARY);
849 JSHandle<BigInt> res6 = BigInt::SignedRightShift(thread, bigint2, shift3);
850 EXPECT_TRUE(BigInt::Equal(res6.GetTaggedValue(), expectRes6.GetTaggedValue()));
851
852 JSHandle<BigInt> res7 = BigInt::SignedRightShift(thread, shift3, bigint1);
853 JSHandle<BigInt> expectRes7 = BigInt::Int32ToBigInt(thread, -1);
854 EXPECT_TRUE(BigInt::Equal(res7.GetTaggedValue(), expectRes7.GetTaggedValue()));
855
856 JSHandle<BigInt> shift4 = BigInt::Int32ToBigInt(thread, 65); // 65 : shiftBits
857 JSHandle<BigInt> res8 = BigInt::SignedRightShift(thread, shift3, shift4);
858 EXPECT_TRUE(BigInt::Equal(res8.GetTaggedValue(), expectRes7.GetTaggedValue()));
859 }
860
861 /**
862 * @tc.name: LeftShift
863 * @tc.desc:
864 * @tc.type: FUNC
865 * @tc.require:
866 */
HWTEST_F_L0(JSBigintTest,LeftShift)867 HWTEST_F_L0(JSBigintTest, LeftShift)
868 {
869 // the left operand is a positive number
870 CString bigintStr1 = "111111011011110111111101111111101111111111110111111111110111111011";
871 JSHandle<BigInt> bigint1 = BigIntHelper::SetBigInt(thread, bigintStr1, BigInt::BINARY);
872 JSHandle<BigInt> shift1 = BigInt::Int32ToBigInt(thread, 20); // 20 : shiftBits
873 JSHandle<BigInt> res1 = BigInt::LeftShift(thread, bigint1, shift1);
874
875 CString expectResStr1 =
876 "11111101101111011111110111111110111111111111011111111111011111101100000000000000000000";
877 JSHandle<BigInt> expectRes1 = BigIntHelper::SetBigInt(thread, expectResStr1, BigInt::BINARY);
878 EXPECT_TRUE(BigInt::Equal(res1.GetTaggedValue(), expectRes1.GetTaggedValue()));
879
880 JSHandle<BigInt> shift2 = BigInt::Int32ToBigInt(thread, 0);
881 JSHandle<BigInt> res2 = BigInt::LeftShift(thread, bigint1, shift2);
882 EXPECT_TRUE(BigInt::Equal(res2.GetTaggedValue(), bigint1.GetTaggedValue()));
883
884 JSHandle<BigInt> shift3 = BigInt::Int32ToBigInt(thread, -33); // -33 : shiftBits
885 JSHandle<BigInt> res4 = BigInt::LeftShift(thread, bigint1, shift3);
886 CString expectResStr4 = "111111011011110111111101111111101";
887 JSHandle<BigInt> expectRes4 = BigIntHelper::SetBigInt(thread, expectResStr4, BigInt::BINARY);
888 EXPECT_TRUE(BigInt::Equal(res4.GetTaggedValue(), expectRes4.GetTaggedValue()));
889
890 // left operand is negative number
891 JSHandle<BigInt> bigint2 = BigInt::UnaryMinus(thread, bigint1);
892
893 CString expectResStr5 =
894 "-11111101101111011111110111111110111111111111011111111111011111101100000000000000000000";
895 JSHandle<BigInt> expectRes5 = BigIntHelper::SetBigInt(thread, expectResStr5, BigInt::BINARY);
896 JSHandle<BigInt> res5 = BigInt::LeftShift(thread, bigint2, shift1);
897 EXPECT_TRUE(BigInt::Equal(res5.GetTaggedValue(), expectRes5.GetTaggedValue()));
898
899 CString expectResStr6 = "-111111011011110111111101111111110";
900 JSHandle<BigInt> expectRes6 = BigIntHelper::SetBigInt(thread, expectResStr6, BigInt::BINARY);
901 JSHandle<BigInt> res6 = BigInt::LeftShift(thread, bigint2, shift3);
902 EXPECT_TRUE(BigInt::Equal(res6.GetTaggedValue(), expectRes6.GetTaggedValue()));
903 }
904
905 } // namespace panda::test