1/*
2 * Copyright (c) 2021 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 "ecmascript/base/number_helper.h"
17#include "ecmascript/tests/test_helper.h"
18
19using namespace panda::ecmascript;
20using namespace panda::ecmascript::base;
21
22namespace panda::test {
23class NumberHelperTest : public BaseTestWithScope<false> {
24};
25
26/**
27 * @tc.name: IsNaN
28 * @tc.desc: Check whether number is Nan type data through "IsNaN" function.
29 * @tc.type: FUNC
30 * @tc.require:
31 */
32HWTEST_F_L0(NumberHelperTest, IsNaN)
33{
34    JSTaggedValue number1(1.23);
35    EXPECT_FALSE(NumberHelper::IsNaN(number1));
36
37    JSTaggedValue number2(-1.23);
38    EXPECT_FALSE(NumberHelper::IsNaN(number2));
39
40    JSTaggedValue number3(0.0f);
41    EXPECT_FALSE(NumberHelper::IsNaN(number3));
42
43    JSTaggedValue number4(0.0f / 0.0f);
44    EXPECT_TRUE(NumberHelper::IsNaN(number4));
45
46    JSTaggedValue number5(NAN_VALUE);
47    EXPECT_TRUE(NumberHelper::IsNaN(number5));
48}
49
50/**
51 * @tc.name: DoubleToString
52 * @tc.desc: This function Convert the double type data into a string.first convert it into the corresponding
53 *           hexadecimal number according to the transmitted radix, and convert the hexadecimal number into a
54 *           string.
55 * @tc.type: FUNC
56 * @tc.require:
57 */
58HWTEST_F_L0(NumberHelperTest, DoubleToString_001)
59{
60    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
61    int radix;
62    radix = 2;
63    JSHandle<EcmaString> resultStr = factory->NewFromASCII("100101");
64    JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToString(thread, 37, radix));
65    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
66
67    radix = 3;
68    resultStr = factory->NewFromASCII("-1101");
69    JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToString(thread, -37, radix));
70    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
71
72    radix = 4;
73    resultStr = factory->NewFromASCII("211");
74    JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToString(thread, 37, radix));
75    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
76
77    radix = 5;
78    resultStr = factory->NewFromASCII("122");
79    JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToString(thread, 37, radix));
80    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
81
82    radix = 5;
83    resultStr = factory->NewFromASCII("-1104332401304422434310320000");
84    JSHandle<EcmaString> handleEcmaStr5(thread,
85        NumberHelper::DoubleToString(thread, static_cast<double>(-9223372036854775807), radix));
86    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
87
88    radix = 6;
89    resultStr = factory->NewFromASCII("101");
90    JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToString(thread, 37, radix));
91    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
92
93    radix = 7;
94    resultStr = factory->NewFromASCII("52");
95    JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToString(thread, 37, radix));
96    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
97
98    radix = 36;
99    resultStr = factory->NewFromASCII("11");
100    JSHandle<EcmaString> handleEcmaStr8(thread, NumberHelper::DoubleToString(thread, 37, radix));
101    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr8, resultStr), 0);
102}
103
104HWTEST_F_L0(NumberHelperTest, DoubleToString_002)
105{
106    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
107    int radix = 2;
108
109    JSHandle<EcmaString> resultStr =
110        factory->NewFromASCII("10.111111011011000110000101010010001010100110111101");
111    JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToString(thread, 2.99099, radix));
112    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
113
114    resultStr = factory->NewFromASCII("10.000000101001000000000011111011101010001000001001101");
115    JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToString(thread, 2.01001, radix));
116    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
117
118    resultStr = factory->NewFromASCII("10.100000000000011010001101101110001011101011000111001");
119    JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToString(thread, 2.5001, radix));
120    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
121
122    radix = 36;
123    resultStr = factory->NewFromASCII("0.i04nym8equ");
124    JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToString(thread, 0.5001, radix));
125    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
126
127    resultStr = factory->NewFromASCII("0.wej2d0mt58f");
128    JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToString(thread, 0.9001, radix));
129    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
130
131    resultStr = factory->NewFromASCII("0.0d384dldb02");
132    JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToString(thread, 0.0101, radix));
133    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
134}
135
136/**
137 * @tc.name: DoubleToEcmaString
138 * @tc.desc: This function Convert the double type data into a EcmaString.
139 * @tc.type: FUNC
140 * @tc.require:
141 */
142HWTEST_F_L0(NumberHelperTest, DoubleToEcmaString)
143{
144    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
145
146    JSHandle<EcmaString> resultStr1 =
147        factory->NewFromASCII("5562684646268003");
148    double d1 = 5562684646268003;
149    JSHandle<EcmaString> resultJSHandle1 = NumberHelper::DoubleToEcmaString(thread, d1);
150    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle1, resultStr1), 0);
151
152    JSHandle<EcmaString> resultStr2 =
153        factory->NewFromASCII("0.005431");
154    double d2 = 0.005431;
155    JSHandle<EcmaString> resultJSHandle2 = NumberHelper::DoubleToEcmaString(thread, d2);
156    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle2, resultStr2), 0);
157
158    JSHandle<EcmaString> resultStr3 =
159        factory->NewFromASCII("1.9045e-7");
160    double d3 = 0.00000019045;
161    JSHandle<EcmaString> resultJSHandle3 = NumberHelper::DoubleToEcmaString(thread, d3);
162    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle3, resultStr3), 0);
163
164    JSHandle<EcmaString> resultStr4 =
165        factory->NewFromASCII("-79.39773355813419");
166    double d4 = -79.39773355813419;
167    JSHandle<EcmaString> resultJSHandle4 = NumberHelper::DoubleToEcmaString(thread, d4);
168    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle4, resultStr4), 0);
169
170    JSHandle<EcmaString> resultStr5 =
171        factory->NewFromASCII("1e+21");
172    double d5 = 1e21;
173    JSHandle<EcmaString> resultJSHandle5 = NumberHelper::DoubleToEcmaString(thread, d5);
174    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle5, resultStr5), 0);
175
176    JSHandle<EcmaString> resultStr6 =
177        factory->NewFromASCII("340000000000000000");
178    double d6 = 340000000000000000;
179    JSHandle<EcmaString> resultJSHandle6 = NumberHelper::DoubleToEcmaString(thread, d6);
180    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle6, resultStr6), 0);
181
182    JSHandle<EcmaString> resultStr7 =
183        factory->NewFromASCII("12.012345678901234");
184    double d7 = 12.01234567890123456789;
185    JSHandle<EcmaString> resultJSHandle7 = NumberHelper::DoubleToEcmaString(thread, d7);
186    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle7, resultStr7), 0);
187
188    JSHandle<EcmaString> resultStr8 =
189        factory->NewFromASCII("0.0000012345678901234567");
190    double digit8 = 0.000001234567890123456789;
191    JSHandle<EcmaString> resultJSHandle8 = NumberHelper::DoubleToEcmaString(thread, digit8);
192    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle8, resultStr8), 0);
193
194    JSHandle<EcmaString> resultStr9 =
195        factory->NewFromASCII("Infinity");
196    double d9 = std::numeric_limits<double>::infinity();
197    JSHandle<EcmaString> resultJSHandle9 = NumberHelper::DoubleToEcmaString(thread, d9);
198    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle9, resultStr9), 0);
199
200    JSHandle<EcmaString> resultStr10 =
201        factory->NewFromASCII("-Infinity");
202    double d10 = -std::numeric_limits<double>::infinity();
203    JSHandle<EcmaString> resultJSHandle10 = NumberHelper::DoubleToEcmaString(thread, d10);
204    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle10, resultStr10), 0);
205
206    JSHandle<EcmaString> resultStr11 =
207        factory->NewFromASCII("1.7976931348623157e+308");
208    double d11 = 1.797693134862315807937e+308;
209    JSHandle<EcmaString> resultJSHandle11 = NumberHelper::DoubleToEcmaString(thread, d11);
210    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle11, resultStr11), 0);
211
212    JSHandle<EcmaString> resultStr12 =
213        factory->NewFromASCII("-1.7976931348623157e+308");
214    double d12 = -1.797693134862315807937e+308;
215    JSHandle<EcmaString> resultJSHandle12 = NumberHelper::DoubleToEcmaString(thread, d12);
216    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle12, resultStr12), 0);
217
218    JSHandle<EcmaString> resultStr13 =
219        factory->NewFromASCII("2.22507e-308");
220    double d13 = 2.22507e-308;
221    JSHandle<EcmaString> resultJSHandle13 = NumberHelper::DoubleToEcmaString(thread, d13);
222    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle13, resultStr13), 0);
223
224    JSHandle<EcmaString> resultStr14 =
225        factory->NewFromASCII("1.2345678901234568e-7");
226    double digit14 = 0.0000001234567890123456789;
227    JSHandle<EcmaString> resultJSHandle14 = NumberHelper::DoubleToEcmaString(thread, digit14);
228    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle14, resultStr14), 0);
229
230    JSHandle<EcmaString> resultStr15 =
231        factory->NewFromASCII("3.4e+21");
232    double digit15 = 3.4e21;
233    JSHandle<EcmaString> resultJSHandle15 = NumberHelper::DoubleToEcmaString(thread, digit15);
234    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle15, resultStr15), 0);
235
236    JSHandle<EcmaString> resultStr16 =
237        factory->NewFromASCII("120000000000000000000");
238    double digit16 = 1.2e20;
239    JSHandle<EcmaString> resultJSHandle16 = NumberHelper::DoubleToEcmaString(thread, digit16);
240    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle16, resultStr16), 0);
241
242    JSHandle<EcmaString> resultStr17 =
243        factory->NewFromASCII("1.2");
244    double digit17 = 1.2e0;
245    JSHandle<EcmaString> resultJSHandle17 = NumberHelper::DoubleToEcmaString(thread, digit17);
246    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle17, resultStr17), 0);
247
248    JSHandle<EcmaString> resultStr18 =
249        factory->NewFromASCII("0.0000012");
250    double digit18 = 1.2e-6;
251    JSHandle<EcmaString> resultJSHandle18 = NumberHelper::DoubleToEcmaString(thread, digit18);
252    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle18, resultStr18), 0);
253
254    JSHandle<EcmaString> resultStr19 =
255        factory->NewFromASCII("1.2e-7");
256    double digit19 = 1.2e-7;
257    JSHandle<EcmaString> resultJSHandle19 = NumberHelper::DoubleToEcmaString(thread, digit19);
258    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle19, resultStr19), 0);
259
260    JSHandle<EcmaString> resultStr20 =
261        factory->NewFromASCII("NaN");
262    double digit20 = std::numeric_limits<double>::quiet_NaN();
263    JSHandle<EcmaString> resultJSHandle20 = NumberHelper::DoubleToEcmaString(thread, digit20);
264    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle20, resultStr20), 0);
265
266    JSHandle<EcmaString> resultStr21 =
267        factory->NewFromASCII("-12.012345678901234");
268    double d21 = -12.01234567890123456789;
269    JSHandle<EcmaString> resultJSHandle21 = NumberHelper::DoubleToEcmaString(thread, d21);
270    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle21, resultStr21), 0);
271
272    JSHandle<EcmaString> resultStr22 =
273        factory->NewFromASCII("-0.0000012345678901234567");
274    double digit22 = -0.000001234567890123456789;
275    JSHandle<EcmaString> resultJSHandle22 = NumberHelper::DoubleToEcmaString(thread, digit22);
276    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle22, resultStr22), 0);
277
278    JSHandle<EcmaString> resultStr23 =
279        factory->NewFromASCII("-1.2345678901234568e-7");
280    double digit23 = -0.0000001234567890123456789;
281    JSHandle<EcmaString> resultJSHandle23 = NumberHelper::DoubleToEcmaString(thread, digit23);
282    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle23, resultStr23), 0);
283
284    JSHandle<EcmaString> resultStr24 =
285        factory->NewFromASCII("-3.4e+21");
286    double digit24 = -3.4e21;
287    JSHandle<EcmaString> resultJSHandle24 = NumberHelper::DoubleToEcmaString(thread, digit24);
288    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle24, resultStr24), 0);
289
290    JSHandle<EcmaString> resultStr25 =
291        factory->NewFromASCII("-120000000000000000000");
292    double digit25 = -1.2e20;
293    JSHandle<EcmaString> resultJSHandle25 = NumberHelper::DoubleToEcmaString(thread, digit25);
294    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle25, resultStr25), 0);
295
296    JSHandle<EcmaString> resultStr26 =
297        factory->NewFromASCII("-1.2");
298    double digit26 = -1.2e0;
299    JSHandle<EcmaString> resultJSHandle26 = NumberHelper::DoubleToEcmaString(thread, digit26);
300    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle26, resultStr26), 0);
301
302    JSHandle<EcmaString> resultStr27 =
303        factory->NewFromASCII("-0.0000012");
304    double digit27 = -1.2e-6;
305    JSHandle<EcmaString> resultJSHandle27 = NumberHelper::DoubleToEcmaString(thread, digit27);
306    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle27, resultStr27), 0);
307
308    JSHandle<EcmaString> resultStr28 =
309        factory->NewFromASCII("-1.2e-7");
310    double digit28 = -1.2e-7;
311    JSHandle<EcmaString> resultJSHandle28 = NumberHelper::DoubleToEcmaString(thread, digit28);
312    EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle28, resultStr28), 0);
313}
314
315/**
316 * @tc.name: IsEmptyString
317 * @tc.desc: Check whether the character is empty string through "IsEmptyString" function.
318 * @tc.type: FUNC
319 * @tc.require:
320 */
321HWTEST_F_L0(NumberHelperTest, IsEmptyString_001)
322{
323    // 9 ~ 13 and 32 belong to empty string
324    uint8_t a[] = {0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x20};
325    for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
326        EXPECT_TRUE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
327    }
328}
329
330HWTEST_F_L0(NumberHelperTest, IsEmptyString_002)
331{
332    // 14 ~ 31 not belong to empty string
333    uint8_t a[] = {0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
334                                      0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
335    for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
336        EXPECT_FALSE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
337    }
338}
339
340HWTEST_F_L0(NumberHelperTest, IsEmptyString_003)
341{
342    // 0 ~ 8 not belong to empty string
343    uint8_t a[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
344    for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
345        EXPECT_FALSE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
346    }
347}
348
349HWTEST_F_L0(NumberHelperTest, IsEmptyString_004)
350{
351    // 160 belong to empty string
352    uint16_t c = 160;
353    utf_helper::Utf8Char d = utf_helper::ConvertUtf16ToUtf8(c, 0, true);
354    EXPECT_EQ(d.ch.at(1), 160);
355    uint8_t b = d.ch.at(1);
356    EXPECT_TRUE(NumberHelper::IsEmptyString(&b, &b + 1));
357}
358
359/**
360 * @tc.name: TruncateDouble
361 * @tc.desc:This function takes the integer part of double type.When it is positive,it is rounded down
362 *          When it is negative,it is rounded up.
363 * @tc.type: FUNC
364 * @tc.require:
365 */
366HWTEST_F_L0(NumberHelperTest, TruncateDouble)
367{
368    EXPECT_EQ(NumberHelper::TruncateDouble(NAN_VALUE), 0);
369    EXPECT_EQ(NumberHelper::TruncateDouble(POSITIVE_INFINITY), POSITIVE_INFINITY);
370    // round down
371    EXPECT_EQ(NumberHelper::TruncateDouble(4.1), 4);
372    EXPECT_EQ(NumberHelper::TruncateDouble(4.9), 4);
373    EXPECT_EQ(NumberHelper::TruncateDouble(101.111), 101);
374    EXPECT_EQ(NumberHelper::TruncateDouble(101.999), 101);
375    // round up
376    EXPECT_EQ(NumberHelper::TruncateDouble(-4.1), -4);
377    EXPECT_EQ(NumberHelper::TruncateDouble(-4.9), -4);
378    EXPECT_EQ(NumberHelper::TruncateDouble(-101.111), -101);
379    EXPECT_EQ(NumberHelper::TruncateDouble(-101.999), -101);
380}
381
382/**
383 * @tc.name: DoubleToInt
384 * @tc.desc: This function takes the double of integer type.When the decimal part is eight and the number of digits
385 *           is 15 ~ 16, add one to convert to integer.According to the binary digits of the integer part,it is divided
386 *           into 8, 16 and 64 hexadecimal conversion,for example, 8-hexadecimal conversion.The maximum value of the
387 *           integer part is 255. If it exceeds 255,the conversion fails.
388 * @tc.type: FUNC
389 * @tc.require:
390 */
391HWTEST_F_L0(NumberHelperTest, DoubleToInt_001)
392{
393    EXPECT_EQ(NumberHelper::DoubleToInt(9.0, INT8_BITS), 9);
394    EXPECT_EQ(NumberHelper::DoubleToInt(9.5555555555555559, INT8_BITS), 9);
395    EXPECT_EQ(NumberHelper::DoubleToInt(9.9999999999999999, INT8_BITS), 10);
396    EXPECT_EQ(NumberHelper::DoubleToInt(128.123456, INT8_BITS), 128);
397    EXPECT_EQ(NumberHelper::DoubleToInt(-128.987654321, INT8_BITS), -128);
398
399    // the exponential bit digits exceeds 7
400    EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT8_BITS), 0);
401    EXPECT_EQ(NumberHelper::DoubleToInt(-256.0, INT8_BITS), 0);
402
403    double nanDouble = 0.0f / 0.0f;
404    EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT8_BITS), 0);
405    double infDouble = POSITIVE_INFINITY;
406    EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT8_BITS), 0);
407}
408
409HWTEST_F_L0(NumberHelperTest, DoubleToInt_002)
410{
411    EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT16_BITS), 256);
412    EXPECT_EQ(NumberHelper::DoubleToInt(256.555555555555556, INT16_BITS), 256);
413    EXPECT_EQ(NumberHelper::DoubleToInt(256.999999999999999, INT16_BITS), 257);
414    EXPECT_EQ(NumberHelper::DoubleToInt(1024.56789, INT16_BITS), 1024);
415    EXPECT_EQ(NumberHelper::DoubleToInt(-1024.987654, INT16_BITS), -1024);
416
417    // the exponential bit digits exceeds 15
418    EXPECT_EQ(NumberHelper::DoubleToInt(65536.0, INT16_BITS), 0);
419    EXPECT_EQ(NumberHelper::DoubleToInt(-65536.0, INT16_BITS), 0);
420
421    double nanDouble = 0.0f / 0.0f;
422    EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT16_BITS), 0);
423    double infDouble = POSITIVE_INFINITY;
424    EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT16_BITS), 0);
425}
426
427HWTEST_F_L0(NumberHelperTest, DoubleToInt_003)
428{
429    EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT64_BITS), 256);
430    EXPECT_EQ(NumberHelper::DoubleToInt(256.555555555555556, INT64_BITS), 256);
431    EXPECT_EQ(NumberHelper::DoubleToInt(256.999999999999999, INT64_BITS), 257);
432    EXPECT_EQ(NumberHelper::DoubleToInt(65536.55555, INT64_BITS), 65536);
433    EXPECT_EQ(NumberHelper::DoubleToInt(-65536.99999, INT64_BITS), -65536);
434
435    EXPECT_EQ(NumberHelper::DoubleToInt(2147483647.0, INT64_BITS), 2147483647);
436    EXPECT_EQ(NumberHelper::DoubleToInt(-2147483647.0, INT64_BITS), -2147483647);
437
438    double nanDouble = 0.0f / 0.0f;
439    EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT64_BITS), 0);
440    double infDouble = POSITIVE_INFINITY;
441    EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT64_BITS), 0);
442}
443
444/**
445 * @tc.name: DoubleInRangeInt32
446 * @tc.desc: The function is to convert double type to int type,The maximum value of integer part of double type
447 *           cannot exceed the maximum value of int, and the minimum value of integer part cannot exceed the
448 *           minimum value of int.
449 * @tc.type: FUNC
450 * @tc.require:
451 */
452HWTEST_F_L0(NumberHelperTest, DoubleInRangeInt32)
453{
454    // more than INT_MAX
455    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(2147483649.0), 2147483647);
456    // less than INT_MIN
457    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-2147483649.0), -2147483648);
458
459    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(128.0), 128);
460    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-128.999999999999999), -129);
461    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(256.0), 256);
462    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-256.0), -256);
463    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(12345.6789), 12345);
464    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-12345.6789), -12345);
465    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(65535.999999999999999), 65536);
466    EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-65535), -65535);
467}
468
469/**
470 * @tc.name: DoubleToExponential
471 * @tc.desc: Convert integer type to string type through "DoubleToExponential" function.
472 * @tc.type: FUNC
473 * @tc.require:
474 */
475HWTEST_F_L0(NumberHelperTest, DoubleToExponential01)
476{
477    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
478    int radix;
479
480    radix = 0;
481    JSHandle<EcmaString> resultStr = factory->NewFromASCII("1.12356e-4");
482    JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToExponential(thread,
483                                        0.00011235600000000001, radix));
484    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
485
486    radix = 1;
487    resultStr = factory->NewFromASCII("1e-4");
488    JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToExponential(thread,
489                                        0.00011235600000000001, radix));
490    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
491
492    radix = 2;
493    resultStr = factory->NewFromASCII("1.1e-4");
494    JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToExponential(thread,
495                                        0.00011235600000000001, radix));
496    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
497
498    radix = 16;
499    resultStr = factory->NewFromASCII("1.123560000000000e-4");
500    JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToExponential(thread,
501                                        0.00011235600000000001, radix));
502    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
503
504    radix = 0;
505    resultStr = factory->NewFromASCII("1.23456e+2");
506    JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
507    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
508
509    radix = 1;
510    resultStr = factory->NewFromASCII("1e+2");
511    JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
512    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
513
514    radix = 2;
515    resultStr = factory->NewFromASCII("1.2e+2");
516    JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
517    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
518
519    radix = 16;
520    resultStr = factory->NewFromASCII("1.234560000000000e+2");
521    JSHandle<EcmaString> handleEcmaStr8(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
522    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr8, resultStr), 0);
523}
524
525HWTEST_F_L0(NumberHelperTest, DoubleToExponential02)
526{
527    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
528    int radix;
529
530    radix = -4;
531    JSHandle<EcmaString> resultStr = factory->NewFromASCII("1.239876e+2");
532    JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
533    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
534
535    radix = -6;
536    resultStr = factory->NewFromASCII("1.239876e+2");
537    JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
538    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
539
540    radix = 3;
541    resultStr = factory->NewFromASCII("1.24e+2");
542    JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToExponential(thread, 123.567, radix));
543    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
544
545    radix = 7;
546    resultStr = factory->NewFromASCII("1.234567e+2");
547    JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToExponential(thread, 123.4567, radix));
548    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
549
550    radix = 8;
551    resultStr = factory->NewFromASCII("1.2345670e+2");
552    JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToExponential(thread, 123.45670, radix));
553    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
554
555    radix = 4;
556    resultStr = factory->NewFromASCII("1.230e+2");
557    JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToExponential(thread, 123.0123, radix));
558    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
559}
560
561/**
562 * @tc.name: StringToDoubleWithRadix
563 * @tc.desc: Convert double decimal type to Precision type through "DoubleToPrecision" function.If the logarithm
564 *           of number based on ten is less than zero and radix Digit is more than zero or it is greater than zero
565 *           and radix Digit is less than MAX_EXPONENT_DIGIT call the DoubleToFixed function.other call
566 *           DoubleToExponential function.
567 * @tc.type: FUNC
568 * @tc.require:
569 */
570HWTEST_F_L0(NumberHelperTest, StringToDoubleWithRadix)
571{
572    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
573    int radix;
574    Span<const uint8_t> sp;
575    CVector<uint8_t> buf;
576    JSHandle<EcmaString> resultStr;
577
578    radix = 3;
579    resultStr = factory->NewFromASCII("-12");
580    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
581    bool negative = false;
582    // 5 = 1 * 3 + 2
583    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), -5);
584
585    radix = 4;
586    resultStr = factory->NewFromASCII("1234567");
587    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
588    negative = false;
589    // 27 = (1 * 4 + 2) * 4 + 3
590    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 27);
591    // string has space
592    resultStr = factory->NewFromASCII(" 12345 ");
593    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
594    negative = false;
595    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 27);
596
597    radix = 16;
598    resultStr = factory->NewFromASCII("0x00ff");
599    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
600    negative = false;
601    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 255);
602
603    resultStr = factory->NewFromASCII("0x0010");
604    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
605    negative = false;
606    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 16);
607
608    resultStr = factory->NewFromASCII("0x1234");
609    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
610    negative = false;
611    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 4660);
612    // string has space
613    resultStr = factory->NewFromASCII(" 0x12  ");
614    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
615    negative = false;
616    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 18);
617
618    resultStr = factory->NewFromASCII("0x1234XX");
619    sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
620    negative = false;
621    EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 4660);
622}
623
624/**
625 * @tc.name: IntToString
626 * @tc.desc: Convert integer type to string type through "IntToString" function.
627 * @tc.type: FUNC
628 * @tc.require:
629 */
630HWTEST_F_L0(NumberHelperTest, IntToString)
631{
632    EXPECT_STREQ(NumberHelper::IntToString(0).c_str(), "0");
633    EXPECT_STREQ(NumberHelper::IntToString(-100).c_str(), "-100");
634    EXPECT_STREQ(NumberHelper::IntToString(123).c_str(), "123");
635    EXPECT_STREQ(NumberHelper::IntToString(1234).c_str(), "1234");
636}
637
638/**
639 * @tc.name: IntegerToString
640 * @tc.desc: Convert the decimal number into the hexadecimal number corresponding to Radix and convert it into a string
641 *           Check whether the returned string result is the same as the actual conversion result.
642 * @tc.type: FUNC
643 * @tc.require:
644 */
645HWTEST_F_L0(NumberHelperTest, IntegerToString)
646{
647    int radix = 2;
648    // number = (radix + 1) * MAX_MANTISSA
649    CString integerStr = NumberHelper::IntegerToString(static_cast<double>((radix + 1) * (0x1ULL << 52U)), radix);
650    EXPECT_STREQ(integerStr.c_str(), "110000000000000000000000000000000000000000000000000000");
651
652    integerStr = NumberHelper::IntegerToString(static_cast<double>(10), radix);
653    EXPECT_STREQ(integerStr.c_str(), "1010");
654
655    radix = 3;
656    integerStr = NumberHelper::IntegerToString(static_cast<double>(33), radix);
657    EXPECT_STREQ(integerStr.c_str(), "1020");
658
659    radix = 8;
660    integerStr = NumberHelper::IntegerToString(static_cast<double>(128), radix);
661    EXPECT_STREQ(integerStr.c_str(), "200");
662
663    integerStr = NumberHelper::IntegerToString(static_cast<double>(128.985), radix);
664    EXPECT_STREQ(integerStr.c_str(), "200");
665
666    radix = 16;
667    integerStr = NumberHelper::IntegerToString(static_cast<double>(256), radix);
668    EXPECT_STREQ(integerStr.c_str(), "100");
669
670    radix = 24;
671    integerStr = NumberHelper::IntegerToString(static_cast<double>(987654), radix);
672    EXPECT_STREQ(integerStr.c_str(), "2nag6");
673
674    integerStr = NumberHelper::IntegerToString(static_cast<double>(23), radix);
675    EXPECT_STREQ(integerStr.c_str(), "n");
676}
677
678/**
679 * @tc.name: NumberToString
680 * @tc.desc: The abstract operation NumberToString converts a Number m to String format
681 * @tc.type: FUNC
682 * @tc.require:
683 */
684HWTEST_F_L0(NumberHelperTest, NumberToString)
685{
686    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
687    double d = 8.1999999999999993;
688    JSHandle<EcmaString> result = NumberHelper::NumberToString(thread, JSTaggedValue(d));
689    JSHandle<EcmaString> target = factory->NewFromASCII("8.2");
690    EXPECT_EQ(EcmaStringAccessor::Compare(instance, result, target), 0);
691
692    double d2 = 0.30000000000000004;
693    JSHandle<EcmaString> result1 = NumberHelper::NumberToString(thread, JSTaggedValue(d2));
694    JSHandle<EcmaString> target1 = factory->NewFromASCII("0.30000000000000004");
695    EXPECT_EQ(EcmaStringAccessor::Compare(instance, result1, target1), 0);
696}
697
698/**
699 * @tc.name: DoubleToInt64
700 * @tc.desc: The abstract operation DoubleToInt64 converts a double value to int64_t
701 * @tc.type: FUNC
702 * @tc.require:
703 */
704HWTEST_F_L0(NumberHelperTest, DoubleToInt64)
705{
706    int64_t d = NumberHelper::DoubleToInt64(std::numeric_limits<double>::max());
707    EXPECT_EQ(d, std::numeric_limits<int64_t>::max());
708
709    int64_t d1 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()));
710    EXPECT_EQ(d1, std::numeric_limits<int64_t>::max());
711    int64_t d2 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()));
712    EXPECT_EQ(d2, std::numeric_limits<int64_t>::min());
713
714    int64_t d3 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()) + 1);
715    EXPECT_EQ(d3, std::numeric_limits<int64_t>::max());
716    int64_t d4 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()) - 1);
717    EXPECT_EQ(d4, std::numeric_limits<int64_t>::min());
718
719    int64_t d5 = NumberHelper::DoubleToInt64(0);
720    EXPECT_EQ(d5, 0);
721}
722/**
723 * @tc.name: DoubleToASCII
724 * @tc.desc: When flag is equal to 2, the calculation result of DoubleToASCII is number.toFixed()
725 * @tc.type: FUNC
726 * @tc.require:
727 */
728
729HWTEST_F_L0(NumberHelperTest, DoubleToASCII_001)
730{
731    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
732    int flags = 2;
733    int digit = 2;
734    JSHandle<EcmaString> resultStr = factory->NewFromASCII("0.10");
735    JSHandle<EcmaString> handleEcmaStr(thread, NumberHelper::DoubleToASCII(thread,
736                                       0.10000000000000001, digit, flags));
737    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr, resultStr), 0);
738
739    digit = 3;
740    resultStr = factory->NewFromASCII("0.100");
741    JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToASCII(thread,
742                                        0.10000000000000001, digit, flags));
743    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
744
745    digit = 2;
746    resultStr = factory->NewFromASCII("0.01");
747    JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToASCII(thread,
748                                        0.01, digit, flags));
749    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
750
751    digit = 3;
752    resultStr = factory->NewFromASCII("0.010");
753    JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToASCII(thread,
754                                        0.01, digit, flags));
755    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
756
757    digit = 7;
758    resultStr = factory->NewFromASCII("0.0000006");
759    JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToASCII(thread,
760                                        5.9999999999999997e-07, digit, flags));
761    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
762
763    digit = 8;
764    resultStr = factory->NewFromASCII("0.00000006");
765    JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToASCII(thread,
766                                        5.9999999999999997e-08, digit, flags));
767    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
768
769    digit = 1;
770#ifdef PANDA_TARGET_ARM32
771    resultStr = factory->NewFromASCII("1.2");
772#else
773    resultStr = factory->NewFromASCII("1.3");
774#endif
775    JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToASCII(thread, 1.25, digit, flags));
776    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
777
778    digit = 1;
779#ifdef PANDA_TARGET_ARM32
780    resultStr = factory->NewFromASCII("-1.2");
781#else
782    resultStr = factory->NewFromASCII("-1.3");
783#endif
784    JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToASCII(thread, -1.25, digit, flags));
785    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
786}
787
788/**
789 * @tc.name: DoubleToASCII
790 * @tc.desc: When flag is equal to 1, the calculation result of DoubleToASCII is number.toPrecision()
791 * @tc.type: FUNC
792 * @tc.require:
793 */
794HWTEST_F_L0(NumberHelperTest, DoubleToASCII_002)
795{
796    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
797    int flags = 1;
798    int digit = 2;
799    JSHandle<EcmaString> resultStr = factory->NewFromASCII("-1.2e-9");
800    JSHandle<EcmaString> handleEcmaStr(thread, NumberHelper::DoubleToASCII(thread, -1.2345e-09, digit, flags));
801    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr, resultStr), 0);
802
803    digit = 2;
804    flags = 1;
805    resultStr = factory->NewFromASCII("1.2e-8");
806    JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToASCII(thread,
807                                        1.2345000000000001e-08, digit, flags));
808    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
809
810    digit = 2;
811    flags = 1;
812#ifdef PANDA_TARGET_ARM32
813    resultStr = factory->NewFromASCII("1.2");
814#else
815    resultStr = factory->NewFromASCII("1.3");
816#endif
817    JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToASCII(thread, 1.25, digit, flags));
818    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
819
820    digit = 2;
821    flags = 1;
822    resultStr = factory->NewFromASCII("1.4");
823    JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToASCII(thread, 1.35, digit, flags));
824    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
825
826
827    digit = 15;
828    flags = 1;
829    resultStr = factory->NewFromASCII("0.000555000000000000");
830    JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToASCII(thread,
831                                        0.00055500000000000005, digit, flags));
832    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
833
834    digit = 15;
835    flags = 1;
836    resultStr = factory->NewFromASCII("5.55000000000000e-7");
837    JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToASCII(thread,
838                                        5.5499999999999998e-07, digit, flags));
839    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
840
841    digit = 15;
842    flags = 1;
843    resultStr = factory->NewFromASCII("-5.55000000000000e-7");
844    JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToASCII(thread,
845                                        -5.5499999999999998e-07, digit, flags));
846    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
847
848    digit = 2;
849    flags = 1;
850    resultStr = factory->NewFromASCII("-12");
851    JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToASCII(thread,
852                                        -12.345000000000001, digit, flags));
853    EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
854}
855
856} // namespace panda::ecmascript
857