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
19 using namespace panda::ecmascript;
20 using namespace panda::ecmascript::base;
21
22 namespace panda::test {
23 class NumberHelperTest : public testing::Test {
24 public:
SetUpTestCase()25 static void SetUpTestCase()
26 {
27 GTEST_LOG_(INFO) << "SetUpTestCase";
28 }
29
TearDownTestCase()30 static void TearDownTestCase()
31 {
32 GTEST_LOG_(INFO) << "TearDownCase";
33 }
34
SetUp()35 void SetUp() override
36 {
37 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
38 }
39
TearDown()40 void TearDown() override
41 {
42 TestHelper::DestroyEcmaVMWithScope(instance, scope);
43 }
44
45 EcmaVM *instance {nullptr};
46 EcmaHandleScope *scope {nullptr};
47 JSThread *thread {nullptr};
48 };
49
50 /**
51 * @tc.name: IsNaN
52 * @tc.desc: Check whether number is Nan type data through "IsNaN" function.
53 * @tc.type: FUNC
54 * @tc.require:
55 */
HWTEST_F_L0(NumberHelperTest,IsNaN)56 HWTEST_F_L0(NumberHelperTest, IsNaN)
57 {
58 JSTaggedValue number1(1.23);
59 EXPECT_FALSE(NumberHelper::IsNaN(number1));
60
61 JSTaggedValue number2(-1.23);
62 EXPECT_FALSE(NumberHelper::IsNaN(number2));
63
64 JSTaggedValue number3(0.0f);
65 EXPECT_FALSE(NumberHelper::IsNaN(number3));
66
67 JSTaggedValue number4(0.0f / 0.0f);
68 EXPECT_TRUE(NumberHelper::IsNaN(number4));
69
70 JSTaggedValue number5(NAN_VALUE);
71 EXPECT_TRUE(NumberHelper::IsNaN(number5));
72 }
73
74 /**
75 * @tc.name: DoubleToString
76 * @tc.desc: This function Convert the double type data into a string.first convert it into the corresponding
77 * hexadecimal number according to the transmitted radix, and convert the hexadecimal number into a
78 * string.
79 * @tc.type: FUNC
80 * @tc.require:
81 */
HWTEST_F_L0(NumberHelperTest,DoubleToString_001)82 HWTEST_F_L0(NumberHelperTest, DoubleToString_001)
83 {
84 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
85 int radix;
86 radix = 2;
87 JSHandle<EcmaString> resultStr = factory->NewFromASCII("100101");
88 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToString(thread, 37, radix));
89 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
90
91 radix = 3;
92 resultStr = factory->NewFromASCII("-1101");
93 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToString(thread, -37, radix));
94 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
95
96 radix = 4;
97 resultStr = factory->NewFromASCII("211");
98 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToString(thread, 37, radix));
99 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
100
101 radix = 5;
102 resultStr = factory->NewFromASCII("122");
103 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToString(thread, 37, radix));
104 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
105
106 radix = 5;
107 resultStr = factory->NewFromASCII("-1104332401304422434310320000");
108 JSHandle<EcmaString> handleEcmaStr5(thread,
109 NumberHelper::DoubleToString(thread, static_cast<double>(-9223372036854775807), radix));
110 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
111
112 radix = 6;
113 resultStr = factory->NewFromASCII("101");
114 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToString(thread, 37, radix));
115 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
116
117 radix = 7;
118 resultStr = factory->NewFromASCII("52");
119 JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToString(thread, 37, radix));
120 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
121
122 radix = 36;
123 resultStr = factory->NewFromASCII("11");
124 JSHandle<EcmaString> handleEcmaStr8(thread, NumberHelper::DoubleToString(thread, 37, radix));
125 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr8, resultStr), 0);
126 }
127
HWTEST_F_L0(NumberHelperTest,DoubleToString_002)128 HWTEST_F_L0(NumberHelperTest, DoubleToString_002)
129 {
130 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
131 int radix = 2;
132
133 JSHandle<EcmaString> resultStr =
134 factory->NewFromASCII("10.111111011011000110000101010010001010100110111101");
135 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToString(thread, 2.99099, radix));
136 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
137
138 resultStr = factory->NewFromASCII("10.000000101001000000000011111011101010001000001001101");
139 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToString(thread, 2.01001, radix));
140 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
141
142 resultStr = factory->NewFromASCII("10.100000000000011010001101101110001011101011000111001");
143 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToString(thread, 2.5001, radix));
144 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
145
146 radix = 36;
147 resultStr = factory->NewFromASCII("0.i04nym8equ");
148 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToString(thread, 0.5001, radix));
149 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
150
151 resultStr = factory->NewFromASCII("0.wej2d0mt58f");
152 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToString(thread, 0.9001, radix));
153 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
154
155 resultStr = factory->NewFromASCII("0.0d384dldb02");
156 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToString(thread, 0.0101, radix));
157 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
158 }
159
160 /**
161 * @tc.name: IsEmptyString
162 * @tc.desc: Check whether the character is empty string through "IsEmptyString" function.
163 * @tc.type: FUNC
164 * @tc.require:
165 */
HWTEST_F_L0(NumberHelperTest,IsEmptyString_001)166 HWTEST_F_L0(NumberHelperTest, IsEmptyString_001)
167 {
168 // 9 ~ 13 and 32 belong to empty string
169 uint8_t a[] = {0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x20};
170 for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
171 EXPECT_TRUE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
172 }
173 }
174
HWTEST_F_L0(NumberHelperTest,IsEmptyString_002)175 HWTEST_F_L0(NumberHelperTest, IsEmptyString_002)
176 {
177 // 14 ~ 31 not belong to empty string
178 uint8_t a[] = {0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
179 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
180 for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
181 EXPECT_FALSE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
182 }
183 }
184
HWTEST_F_L0(NumberHelperTest,IsEmptyString_003)185 HWTEST_F_L0(NumberHelperTest, IsEmptyString_003)
186 {
187 // 0 ~ 8 not belong to empty string
188 uint8_t a[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
189 for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
190 EXPECT_FALSE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
191 }
192 }
193
HWTEST_F_L0(NumberHelperTest,IsEmptyString_004)194 HWTEST_F_L0(NumberHelperTest, IsEmptyString_004)
195 {
196 // 160 belong to empty string
197 uint16_t c = 160;
198 utf_helper::Utf8Char d = utf_helper::ConvertUtf16ToUtf8(c, 0, true);
199 EXPECT_EQ(d.ch.at(1), 160);
200 uint8_t b = d.ch.at(1);
201 EXPECT_TRUE(NumberHelper::IsEmptyString(&b, &b + 1));
202 }
203
204 /**
205 * @tc.name: TruncateDouble
206 * @tc.desc:This function takes the integer part of double type.When it is positive,it is rounded down
207 * When it is negative,it is rounded up.
208 * @tc.type: FUNC
209 * @tc.require:
210 */
HWTEST_F_L0(NumberHelperTest,TruncateDouble)211 HWTEST_F_L0(NumberHelperTest, TruncateDouble)
212 {
213 EXPECT_EQ(NumberHelper::TruncateDouble(NAN_VALUE), 0);
214 EXPECT_EQ(NumberHelper::TruncateDouble(POSITIVE_INFINITY), POSITIVE_INFINITY);
215 // round down
216 EXPECT_EQ(NumberHelper::TruncateDouble(4.1), 4);
217 EXPECT_EQ(NumberHelper::TruncateDouble(4.9), 4);
218 EXPECT_EQ(NumberHelper::TruncateDouble(101.111), 101);
219 EXPECT_EQ(NumberHelper::TruncateDouble(101.999), 101);
220 // round up
221 EXPECT_EQ(NumberHelper::TruncateDouble(-4.1), -4);
222 EXPECT_EQ(NumberHelper::TruncateDouble(-4.9), -4);
223 EXPECT_EQ(NumberHelper::TruncateDouble(-101.111), -101);
224 EXPECT_EQ(NumberHelper::TruncateDouble(-101.999), -101);
225 }
226
227 /**
228 * @tc.name: DoubleToInt
229 * @tc.desc: This function takes the double of integer type.When the decimal part is eight and the number of digits
230 * is 15 ~ 16, add one to convert to integer.According to the binary digits of the integer part,it is divided
231 * into 8, 16 and 64 hexadecimal conversion,for example, 8-hexadecimal conversion.The maximum value of the
232 * integer part is 255. If it exceeds 255,the conversion fails.
233 * @tc.type: FUNC
234 * @tc.require:
235 */
HWTEST_F_L0(NumberHelperTest,DoubleToInt_001)236 HWTEST_F_L0(NumberHelperTest, DoubleToInt_001)
237 {
238 EXPECT_EQ(NumberHelper::DoubleToInt(9.0, INT8_BITS), 9);
239 EXPECT_EQ(NumberHelper::DoubleToInt(9.5555555555555559, INT8_BITS), 9);
240 EXPECT_EQ(NumberHelper::DoubleToInt(9.9999999999999999, INT8_BITS), 10);
241 EXPECT_EQ(NumberHelper::DoubleToInt(128.123456, INT8_BITS), 128);
242 EXPECT_EQ(NumberHelper::DoubleToInt(-128.987654321, INT8_BITS), -128);
243
244 // the exponential bit digits exceeds 7
245 EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT8_BITS), 0);
246 EXPECT_EQ(NumberHelper::DoubleToInt(-256.0, INT8_BITS), 0);
247
248 double nanDouble = 0.0f / 0.0f;
249 EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT8_BITS), 0);
250 double infDouble = POSITIVE_INFINITY;
251 EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT8_BITS), 0);
252 }
253
HWTEST_F_L0(NumberHelperTest,DoubleToInt_002)254 HWTEST_F_L0(NumberHelperTest, DoubleToInt_002)
255 {
256 EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT16_BITS), 256);
257 EXPECT_EQ(NumberHelper::DoubleToInt(256.555555555555556, INT16_BITS), 256);
258 EXPECT_EQ(NumberHelper::DoubleToInt(256.999999999999999, INT16_BITS), 257);
259 EXPECT_EQ(NumberHelper::DoubleToInt(1024.56789, INT16_BITS), 1024);
260 EXPECT_EQ(NumberHelper::DoubleToInt(-1024.987654, INT16_BITS), -1024);
261
262 // the exponential bit digits exceeds 15
263 EXPECT_EQ(NumberHelper::DoubleToInt(65536.0, INT16_BITS), 0);
264 EXPECT_EQ(NumberHelper::DoubleToInt(-65536.0, INT16_BITS), 0);
265
266 double nanDouble = 0.0f / 0.0f;
267 EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT16_BITS), 0);
268 double infDouble = POSITIVE_INFINITY;
269 EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT16_BITS), 0);
270 }
271
HWTEST_F_L0(NumberHelperTest,DoubleToInt_003)272 HWTEST_F_L0(NumberHelperTest, DoubleToInt_003)
273 {
274 EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT64_BITS), 256);
275 EXPECT_EQ(NumberHelper::DoubleToInt(256.555555555555556, INT64_BITS), 256);
276 EXPECT_EQ(NumberHelper::DoubleToInt(256.999999999999999, INT64_BITS), 257);
277 EXPECT_EQ(NumberHelper::DoubleToInt(65536.55555, INT64_BITS), 65536);
278 EXPECT_EQ(NumberHelper::DoubleToInt(-65536.99999, INT64_BITS), -65536);
279
280 EXPECT_EQ(NumberHelper::DoubleToInt(2147483647.0, INT64_BITS), 2147483647);
281 EXPECT_EQ(NumberHelper::DoubleToInt(-2147483647.0, INT64_BITS), -2147483647);
282
283 double nanDouble = 0.0f / 0.0f;
284 EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT64_BITS), 0);
285 double infDouble = POSITIVE_INFINITY;
286 EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT64_BITS), 0);
287 }
288
289 /**
290 * @tc.name: DoubleInRangeInt32
291 * @tc.desc: The function is to convert double type to int type,The maximum value of integer part of double type
292 * cannot exceed the maximum value of int, and the minimum value of integer part cannot exceed the
293 * minimum value of int.
294 * @tc.type: FUNC
295 * @tc.require:
296 */
HWTEST_F_L0(NumberHelperTest,DoubleInRangeInt32)297 HWTEST_F_L0(NumberHelperTest, DoubleInRangeInt32)
298 {
299 // more than INT_MAX
300 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(2147483649.0), 2147483647);
301 // less than INT_MIN
302 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-2147483649.0), -2147483648);
303
304 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(128.0), 128);
305 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-128.999999999999999), -129);
306 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(256.0), 256);
307 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-256.0), -256);
308 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(12345.6789), 12345);
309 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-12345.6789), -12345);
310 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(65535.999999999999999), 65536);
311 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-65535), -65535);
312 }
313
314 /**
315 * @tc.name: DoubleToExponential
316 * @tc.desc: Convert integer type to string type through "DoubleToExponential" function.
317 * @tc.type: FUNC
318 * @tc.require:
319 */
HWTEST_F_L0(NumberHelperTest,DoubleToExponential01)320 HWTEST_F_L0(NumberHelperTest, DoubleToExponential01)
321 {
322 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
323 int radix;
324
325 radix = 0;
326 JSHandle<EcmaString> resultStr = factory->NewFromASCII("1.12356e-4");
327 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToExponential(thread,
328 0.00011235600000000001, radix));
329 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
330
331 radix = 1;
332 resultStr = factory->NewFromASCII("1e-4");
333 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToExponential(thread,
334 0.00011235600000000001, radix));
335 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
336
337 radix = 2;
338 resultStr = factory->NewFromASCII("1.1e-4");
339 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToExponential(thread,
340 0.00011235600000000001, radix));
341 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
342
343 radix = 16;
344 resultStr = factory->NewFromASCII("1.123560000000000e-4");
345 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToExponential(thread,
346 0.00011235600000000001, radix));
347 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
348
349 radix = 0;
350 resultStr = factory->NewFromASCII("1.23456e+2");
351 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
352 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
353
354 radix = 1;
355 resultStr = factory->NewFromASCII("1e+2");
356 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
357 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
358
359 radix = 2;
360 resultStr = factory->NewFromASCII("1.2e+2");
361 JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
362 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
363
364 radix = 16;
365 resultStr = factory->NewFromASCII("1.234560000000000e+2");
366 JSHandle<EcmaString> handleEcmaStr8(thread, NumberHelper::DoubleToExponential(thread, 123.456, radix));
367 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr8, resultStr), 0);
368 }
369
HWTEST_F_L0(NumberHelperTest,DoubleToExponential02)370 HWTEST_F_L0(NumberHelperTest, DoubleToExponential02)
371 {
372 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
373 int radix;
374
375 radix = -4;
376 JSHandle<EcmaString> resultStr = factory->NewFromASCII("1.239876e+2");
377 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
378 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
379
380 radix = -6;
381 resultStr = factory->NewFromASCII("1.239876e+2");
382 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
383 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
384
385 radix = 3;
386 resultStr = factory->NewFromASCII("1.24e+2");
387 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToExponential(thread, 123.567, radix));
388 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
389
390 radix = 7;
391 resultStr = factory->NewFromASCII("1.234567e+2");
392 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToExponential(thread, 123.4567, radix));
393 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
394
395 radix = 8;
396 resultStr = factory->NewFromASCII("1.2345670e+2");
397 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToExponential(thread, 123.45670, radix));
398 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
399
400 radix = 4;
401 resultStr = factory->NewFromASCII("1.230e+2");
402 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToExponential(thread, 123.0123, radix));
403 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
404 }
405
406 /**
407 * @tc.name: StringToDoubleWithRadix
408 * @tc.desc: Convert double decimal type to Precision type through "DoubleToPrecision" function.If the logarithm
409 * of number based on ten is less than zero and radix Digit is more than zero or it is greater than zero
410 * and radix Digit is less than MAX_EXPONENT_DIGIT call the DoubleToFixed function.other call
411 * DoubleToExponential function.
412 * @tc.type: FUNC
413 * @tc.require:
414 */
HWTEST_F_L0(NumberHelperTest,StringToDoubleWithRadix)415 HWTEST_F_L0(NumberHelperTest, StringToDoubleWithRadix)
416 {
417 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
418 int radix;
419 Span<const uint8_t> sp;
420 CVector<uint8_t> buf;
421 JSHandle<EcmaString> resultStr;
422
423 radix = 3;
424 resultStr = factory->NewFromASCII("-12");
425 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
426 bool negative = false;
427 // 5 = 1 * 3 + 2
428 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), -5);
429
430 radix = 4;
431 resultStr = factory->NewFromASCII("1234567");
432 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
433 negative = false;
434 // 27 = (1 * 4 + 2) * 4 + 3
435 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 27);
436 // string has space
437 resultStr = factory->NewFromASCII(" 12345 ");
438 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
439 negative = false;
440 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 27);
441
442 radix = 16;
443 resultStr = factory->NewFromASCII("0x00ff");
444 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
445 negative = false;
446 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 255);
447
448 resultStr = factory->NewFromASCII("0x0010");
449 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
450 negative = false;
451 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 16);
452
453 resultStr = factory->NewFromASCII("0x1234");
454 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
455 negative = false;
456 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 4660);
457 // string has space
458 resultStr = factory->NewFromASCII(" 0x12 ");
459 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
460 negative = false;
461 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 18);
462
463 resultStr = factory->NewFromASCII("0x1234XX");
464 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
465 negative = false;
466 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix, &negative).GetDouble(), 4660);
467 }
468
469 /**
470 * @tc.name: IntToString
471 * @tc.desc: Convert integer type to string type through "IntToString" function.
472 * @tc.type: FUNC
473 * @tc.require:
474 */
HWTEST_F_L0(NumberHelperTest,IntToString)475 HWTEST_F_L0(NumberHelperTest, IntToString)
476 {
477 EXPECT_STREQ(NumberHelper::IntToString(0).c_str(), "0");
478 EXPECT_STREQ(NumberHelper::IntToString(-100).c_str(), "-100");
479 EXPECT_STREQ(NumberHelper::IntToString(123).c_str(), "123");
480 EXPECT_STREQ(NumberHelper::IntToString(1234).c_str(), "1234");
481 }
482
483 /**
484 * @tc.name: IntegerToString
485 * @tc.desc: Convert the decimal number into the hexadecimal number corresponding to Radix and convert it into a string
486 * Check whether the returned string result is the same as the actual conversion result.
487 * @tc.type: FUNC
488 * @tc.require:
489 */
HWTEST_F_L0(NumberHelperTest,IntegerToString)490 HWTEST_F_L0(NumberHelperTest, IntegerToString)
491 {
492 int radix = 2;
493 // number = (radix + 1) * MAX_MANTISSA
494 CString integerStr = NumberHelper::IntegerToString(static_cast<double>((radix + 1) * (0x1ULL << 52U)), radix);
495 EXPECT_STREQ(integerStr.c_str(), "110000000000000000000000000000000000000000000000000000");
496
497 integerStr = NumberHelper::IntegerToString(static_cast<double>(10), radix);
498 EXPECT_STREQ(integerStr.c_str(), "1010");
499
500 radix = 3;
501 integerStr = NumberHelper::IntegerToString(static_cast<double>(33), radix);
502 EXPECT_STREQ(integerStr.c_str(), "1020");
503
504 radix = 8;
505 integerStr = NumberHelper::IntegerToString(static_cast<double>(128), radix);
506 EXPECT_STREQ(integerStr.c_str(), "200");
507
508 integerStr = NumberHelper::IntegerToString(static_cast<double>(128.985), radix);
509 EXPECT_STREQ(integerStr.c_str(), "200");
510
511 radix = 16;
512 integerStr = NumberHelper::IntegerToString(static_cast<double>(256), radix);
513 EXPECT_STREQ(integerStr.c_str(), "100");
514
515 radix = 24;
516 integerStr = NumberHelper::IntegerToString(static_cast<double>(987654), radix);
517 EXPECT_STREQ(integerStr.c_str(), "2nag6");
518
519 integerStr = NumberHelper::IntegerToString(static_cast<double>(23), radix);
520 EXPECT_STREQ(integerStr.c_str(), "n");
521 }
522
523 /**
524 * @tc.name: NumberToString
525 * @tc.desc: The abstract operation NumberToString converts a Number m to String format
526 * @tc.type: FUNC
527 * @tc.require:
528 */
HWTEST_F_L0(NumberHelperTest,NumberToString)529 HWTEST_F_L0(NumberHelperTest, NumberToString)
530 {
531 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
532 double d = 8.1999999999999993;
533 JSHandle<EcmaString> result = NumberHelper::NumberToString(thread, JSTaggedValue(d));
534 JSHandle<EcmaString> target = factory->NewFromASCII("8.2");
535 EXPECT_EQ(EcmaStringAccessor::Compare(instance, result, target), 0);
536
537 double d2 = 0.30000000000000004;
538 JSHandle<EcmaString> result1 = NumberHelper::NumberToString(thread, JSTaggedValue(d2));
539 JSHandle<EcmaString> target1 = factory->NewFromASCII("0.30000000000000004");
540 EXPECT_EQ(EcmaStringAccessor::Compare(instance, result1, target1), 0);
541 }
542
543 /**
544 * @tc.name: DoubleToInt64
545 * @tc.desc: The abstract operation DoubleToInt64 converts a double value to int64_t
546 * @tc.type: FUNC
547 * @tc.require:
548 */
HWTEST_F_L0(NumberHelperTest,DoubleToInt64)549 HWTEST_F_L0(NumberHelperTest, DoubleToInt64)
550 {
551 int64_t d = NumberHelper::DoubleToInt64(std::numeric_limits<double>::max());
552 EXPECT_EQ(d, std::numeric_limits<int64_t>::max());
553
554 int64_t d1 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()));
555 EXPECT_EQ(d1, std::numeric_limits<int64_t>::max());
556 int64_t d2 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()));
557 EXPECT_EQ(d2, std::numeric_limits<int64_t>::min());
558
559 int64_t d3 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()) + 1);
560 EXPECT_EQ(d3, std::numeric_limits<int64_t>::max());
561 int64_t d4 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()) - 1);
562 EXPECT_EQ(d4, std::numeric_limits<int64_t>::min());
563
564 int64_t d5 = NumberHelper::DoubleToInt64(0);
565 EXPECT_EQ(d5, 0);
566 }
567 /**
568 * @tc.name: DoubleToASCII
569 * @tc.desc: When flag is equal to 2, the calculation result of DoubleToASCII is number.toFixed()
570 * @tc.type: FUNC
571 * @tc.require:
572 */
573
HWTEST_F_L0(NumberHelperTest,DoubleToASCII_001)574 HWTEST_F_L0(NumberHelperTest, DoubleToASCII_001)
575 {
576 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
577 int flags = 2;
578 int digit = 2;
579 JSHandle<EcmaString> resultStr = factory->NewFromASCII("0.10");
580 JSHandle<EcmaString> handleEcmaStr(thread, NumberHelper::DoubleToASCII(thread,
581 0.10000000000000001, digit, flags));
582 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr, resultStr), 0);
583
584 digit = 3;
585 resultStr = factory->NewFromASCII("0.100");
586 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToASCII(thread,
587 0.10000000000000001, digit, flags));
588 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
589
590 digit = 2;
591 resultStr = factory->NewFromASCII("0.01");
592 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToASCII(thread,
593 0.01, digit, flags));
594 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
595
596 digit = 3;
597 resultStr = factory->NewFromASCII("0.010");
598 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToASCII(thread,
599 0.01, digit, flags));
600 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
601
602 digit = 7;
603 resultStr = factory->NewFromASCII("0.0000006");
604 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToASCII(thread,
605 5.9999999999999997e-07, digit, flags));
606 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
607
608 digit = 8;
609 resultStr = factory->NewFromASCII("0.00000006");
610 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToASCII(thread,
611 5.9999999999999997e-08, digit, flags));
612 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
613
614 digit = 1;
615 #ifdef PANDA_TARGET_ARM32
616 resultStr = factory->NewFromASCII("1.2");
617 #else
618 resultStr = factory->NewFromASCII("1.3");
619 #endif
620 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToASCII(thread, 1.25, digit, flags));
621 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
622
623 digit = 1;
624 #ifdef PANDA_TARGET_ARM32
625 resultStr = factory->NewFromASCII("-1.2");
626 #else
627 resultStr = factory->NewFromASCII("-1.3");
628 #endif
629 JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToASCII(thread, -1.25, digit, flags));
630 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
631 }
632
633 /**
634 * @tc.name: DoubleToASCII
635 * @tc.desc: When flag is equal to 1, the calculation result of DoubleToASCII is number.toPrecision()
636 * @tc.type: FUNC
637 * @tc.require:
638 */
HWTEST_F_L0(NumberHelperTest,DoubleToASCII_002)639 HWTEST_F_L0(NumberHelperTest, DoubleToASCII_002)
640 {
641 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
642 int flags = 1;
643 int digit = 2;
644 JSHandle<EcmaString> resultStr = factory->NewFromASCII("-1.2e-9");
645 JSHandle<EcmaString> handleEcmaStr(thread, NumberHelper::DoubleToASCII(thread, -1.2345e-09, digit, flags));
646 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr, resultStr), 0);
647
648 digit = 2;
649 flags = 1;
650 resultStr = factory->NewFromASCII("1.2e-8");
651 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToASCII(thread,
652 1.2345000000000001e-08, digit, flags));
653 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
654
655 digit = 2;
656 flags = 1;
657 #ifdef PANDA_TARGET_ARM32
658 resultStr = factory->NewFromASCII("1.2");
659 #else
660 resultStr = factory->NewFromASCII("1.3");
661 #endif
662 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToASCII(thread, 1.25, digit, flags));
663 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
664
665 digit = 2;
666 flags = 1;
667 resultStr = factory->NewFromASCII("1.4");
668 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToASCII(thread, 1.35, digit, flags));
669 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
670
671
672 digit = 15;
673 flags = 1;
674 resultStr = factory->NewFromASCII("0.000555000000000000");
675 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToASCII(thread,
676 0.00055500000000000005, digit, flags));
677 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
678
679 digit = 15;
680 flags = 1;
681 resultStr = factory->NewFromASCII("5.55000000000000e-7");
682 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToASCII(thread,
683 5.5499999999999998e-07, digit, flags));
684 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
685
686 digit = 15;
687 flags = 1;
688 resultStr = factory->NewFromASCII("-5.55000000000000e-7");
689 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToASCII(thread,
690 -5.5499999999999998e-07, digit, flags));
691 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
692
693 digit = 2;
694 flags = 1;
695 resultStr = factory->NewFromASCII("-12");
696 JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToASCII(thread,
697 -12.345000000000001, digit, flags));
698 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
699 }
700
701 } // namespace panda::ecmascript