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