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
HWTEST_F_L0(NumberHelperTest,DoubleToExponential)314 HWTEST_F_L0(NumberHelperTest, DoubleToExponential)
315 {
316 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
317 int radix;
318
319 radix = -4;
320 JSHandle<EcmaString> resultStr = factory->NewFromASCII("1.239876e+2");
321 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
322 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
323
324 radix = -6;
325 resultStr = factory->NewFromASCII("1.239876e+2");
326 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
327 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
328
329 radix = 2;
330 resultStr = factory->NewFromASCII("1.24e+2");
331 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToExponential(thread, 123.567, radix));
332 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
333
334 radix = 6;
335 resultStr = factory->NewFromASCII("1.234567e+2");
336 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToExponential(thread, 123.4567, radix));
337 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
338
339 radix = 7;
340 resultStr = factory->NewFromASCII("1.2345670e+2");
341 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToExponential(thread, 123.45670, radix));
342 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
343
344 radix = 3;
345 resultStr = factory->NewFromASCII("1.230e+2");
346 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToExponential(thread, 123.0123, radix));
347 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
348 }
349
HWTEST_F_L0(NumberHelperTest,DoubleToFixed)350 HWTEST_F_L0(NumberHelperTest, DoubleToFixed)
351 {
352 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
353 int radix;
354
355 radix = 1;
356 JSHandle<EcmaString> resultStr = factory->NewFromASCII("123.5");
357 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
358 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
359
360 radix = 2;
361 resultStr = factory->NewFromASCII("123.46");
362 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
363 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
364
365 radix = 3;
366 resultStr = factory->NewFromASCII("123.456");
367 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
368 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
369
370 radix = 4;
371 resultStr = factory->NewFromASCII("123.4560");
372 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
373 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr4, resultStr), 0);
374
375 radix = 0;
376 resultStr = factory->NewFromASCII("123");
377 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
378 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
379 }
380
381 /**
382 * @tc.name: DoubleToPrecision
383 * @tc.desc: Convert double decimal type to Precision type through "DoubleToPrecision" function.If the logarithm
384 * of number based on ten is less than zero and radix Digit is more than zero or it is greater than zero
385 * and radix Digit is less than MAX_EXPONENT_DIGIT call the DoubleToFixed function.other call
386 * DoubleToExponential function.
387 * @tc.type: FUNC
388 * @tc.require:
389 */
HWTEST_F_L0(NumberHelperTest,DoubleToPrecision)390 HWTEST_F_L0(NumberHelperTest, DoubleToPrecision)
391 {
392 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
393 int radix;
394
395 radix = 1;
396 JSHandle<EcmaString> resultStr = factory->NewFromASCII("0");
397 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToPrecision(thread, 0.0, radix));
398 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr1, resultStr), 0);
399
400 resultStr = factory->NewFromASCII("0.0001");
401 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToPrecision(thread, 0.0001, radix));
402 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr2, resultStr), 0);
403
404 resultStr = factory->NewFromASCII("1e-7");
405 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToPrecision(thread, 0.0000001, radix));
406 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr3, resultStr), 0);
407
408 resultStr = factory->NewFromASCII("1e+3");
409 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToPrecision(thread, 1000.1234, radix));
410 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr5, resultStr), 0);
411
412 radix = 6;
413 resultStr = factory->NewFromASCII("1000.12");
414 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToPrecision(thread, 1000.1234, radix));
415 EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr6, resultStr), 0);
416 }
417
418 /**
419 * @tc.name: DoubleToPrecision
420 * @tc.desc: Convert double decimal type to Precision type through "DoubleToPrecision" function.If the logarithm
421 * of number based on ten is less than zero and radix Digit is more than zero or it is greater than zero
422 * and radix Digit is less than MAX_EXPONENT_DIGIT call the DoubleToFixed function.other call
423 * DoubleToExponential function.
424 * @tc.type: FUNC
425 * @tc.require:
426 */
HWTEST_F_L0(NumberHelperTest,StringToDoubleWithRadix)427 HWTEST_F_L0(NumberHelperTest, StringToDoubleWithRadix)
428 {
429 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
430 int radix;
431 Span<const uint8_t> sp;
432 CVector<uint8_t> buf;
433 JSHandle<EcmaString> resultStr;
434
435 radix = 3;
436 resultStr = factory->NewFromASCII("-12");
437 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
438 // 5 = 1 * 3 + 2
439 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), -5);
440
441 radix = 4;
442 resultStr = factory->NewFromASCII("1234567");
443 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
444 // 27 = (1 * 4 + 2) * 4 + 3
445 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 27);
446 // string has space
447 resultStr = factory->NewFromASCII(" 12345 ");
448 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
449 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 27);
450
451 radix = 16;
452 resultStr = factory->NewFromASCII("0x00ff");
453 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
454 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 255);
455
456 resultStr = factory->NewFromASCII("0x0010");
457 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
458 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 16);
459
460 resultStr = factory->NewFromASCII("0x1234");
461 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
462 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 4660);
463 // string has space
464 resultStr = factory->NewFromASCII(" 0x12 ");
465 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
466 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 18);
467
468 resultStr = factory->NewFromASCII("0x1234XX");
469 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
470 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 4660);
471 }
472
473 /**
474 * @tc.name: IntToString
475 * @tc.desc: Convert integer type to string type through "IntToString" function.
476 * @tc.type: FUNC
477 * @tc.require:
478 */
HWTEST_F_L0(NumberHelperTest,IntToString)479 HWTEST_F_L0(NumberHelperTest, IntToString)
480 {
481 EXPECT_STREQ(NumberHelper::IntToString(0).c_str(), "0");
482 EXPECT_STREQ(NumberHelper::IntToString(-100).c_str(), "-100");
483 EXPECT_STREQ(NumberHelper::IntToString(123).c_str(), "123");
484 EXPECT_STREQ(NumberHelper::IntToString(1234).c_str(), "1234");
485 }
486
487 /**
488 * @tc.name: IntegerToString
489 * @tc.desc: Convert the decimal number into the hexadecimal number corresponding to Radix and convert it into a string
490 * Check whether the returned string result is the same as the actual conversion result.
491 * @tc.type: FUNC
492 * @tc.require:
493 */
HWTEST_F_L0(NumberHelperTest,IntegerToString)494 HWTEST_F_L0(NumberHelperTest, IntegerToString)
495 {
496 int radix = 2;
497 // number = (radix + 1) * MAX_MANTISSA
498 CString integerStr = NumberHelper::IntegerToString(static_cast<double>((radix + 1) * (0x1ULL << 52U)), radix);
499 EXPECT_STREQ(integerStr.c_str(), "110000000000000000000000000000000000000000000000000000");
500
501 integerStr = NumberHelper::IntegerToString(static_cast<double>(10), radix);
502 EXPECT_STREQ(integerStr.c_str(), "1010");
503
504 radix = 3;
505 integerStr = NumberHelper::IntegerToString(static_cast<double>(33), radix);
506 EXPECT_STREQ(integerStr.c_str(), "1020");
507
508 radix = 8;
509 integerStr = NumberHelper::IntegerToString(static_cast<double>(128), radix);
510 EXPECT_STREQ(integerStr.c_str(), "200");
511
512 integerStr = NumberHelper::IntegerToString(static_cast<double>(128.985), radix);
513 EXPECT_STREQ(integerStr.c_str(), "200");
514
515 radix = 16;
516 integerStr = NumberHelper::IntegerToString(static_cast<double>(256), radix);
517 EXPECT_STREQ(integerStr.c_str(), "100");
518
519 radix = 24;
520 integerStr = NumberHelper::IntegerToString(static_cast<double>(987654), radix);
521 EXPECT_STREQ(integerStr.c_str(), "2nag6");
522
523 integerStr = NumberHelper::IntegerToString(static_cast<double>(23), radix);
524 EXPECT_STREQ(integerStr.c_str(), "n");
525 }
526
527 /**
528 * @tc.name: NumberToString
529 * @tc.desc: The abstract operation NumberToString converts a Number m to String format
530 * @tc.type: FUNC
531 * @tc.require:
532 */
HWTEST_F_L0(NumberHelperTest,NumberToString)533 HWTEST_F_L0(NumberHelperTest, NumberToString)
534 {
535 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
536 double d = 8.1999999999999993;
537 JSHandle<EcmaString> result = NumberHelper::NumberToString(thread, JSTaggedValue(d));
538 JSHandle<EcmaString> target = factory->NewFromASCII("8.2");
539 EXPECT_EQ(EcmaStringAccessor::Compare(instance, result, target), 0);
540
541 double d2 = 0.30000000000000004;
542 JSHandle<EcmaString> result1 = NumberHelper::NumberToString(thread, JSTaggedValue(d2));
543 JSHandle<EcmaString> target1 = factory->NewFromASCII("0.30000000000000004");
544 EXPECT_EQ(EcmaStringAccessor::Compare(instance, result1, target1), 0);
545 }
546
547 /**
548 * @tc.name: DoubleToInt64
549 * @tc.desc: The abstract operation DoubleToInt64 converts a double value to int64_t
550 * @tc.type: FUNC
551 * @tc.require:
552 */
HWTEST_F_L0(NumberHelperTest,DoubleToInt64)553 HWTEST_F_L0(NumberHelperTest, DoubleToInt64)
554 {
555 int64_t d = NumberHelper::DoubleToInt64(std::numeric_limits<double>::max());
556 EXPECT_EQ(d, std::numeric_limits<int64_t>::max());
557
558 int64_t d1 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()));
559 EXPECT_EQ(d1, std::numeric_limits<int64_t>::max());
560 int64_t d2 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()));
561 EXPECT_EQ(d2, std::numeric_limits<int64_t>::min());
562
563 int64_t d3 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()) + 1);
564 EXPECT_EQ(d3, std::numeric_limits<int64_t>::max());
565 int64_t d4 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()) - 1);
566 EXPECT_EQ(d4, std::numeric_limits<int64_t>::min());
567
568 int64_t d5 = NumberHelper::DoubleToInt64(0);
569 EXPECT_EQ(d5, 0);
570 }
571 } // namespace panda::ecmascript