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(*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(*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(*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(*handleEcmaStr4, *resultStr), 0);
105
106 radix = 6;
107 resultStr = factory->NewFromASCII("101");
108 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToString(thread, 37, radix));
109 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr6, *resultStr), 0);
110
111 radix = 7;
112 resultStr = factory->NewFromASCII("52");
113 JSHandle<EcmaString> handleEcmaStr7(thread, NumberHelper::DoubleToString(thread, 37, radix));
114 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr7, *resultStr), 0);
115
116 radix = 36;
117 resultStr = factory->NewFromASCII("11");
118 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToString(thread, 37, radix));
119 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr5, *resultStr), 0);
120 }
121
HWTEST_F_L0(NumberHelperTest,DoubleToString_002)122 HWTEST_F_L0(NumberHelperTest, DoubleToString_002)
123 {
124 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
125 int radix = 2;
126
127 JSHandle<EcmaString> resultStr =
128 factory->NewFromASCII("10.111111011011000110000101010010001010100110111101");
129 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToString(thread, 2.99099, radix));
130 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr1, *resultStr), 0);
131
132 resultStr = factory->NewFromASCII("10.000000101001000000000011111011101010001000001001101");
133 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToString(thread, 2.01001, radix));
134 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr2, *resultStr), 0);
135
136 resultStr = factory->NewFromASCII("10.100000000000011010001101101110001011101011000111001");
137 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToString(thread, 2.5001, radix));
138 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr3, *resultStr), 0);
139
140 radix = 36;
141 resultStr = factory->NewFromASCII("0.i04nym8equ");
142 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToString(thread, 0.5001, radix));
143 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr4, *resultStr), 0);
144
145 resultStr = factory->NewFromASCII("0.wej2d0mt58f");
146 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToString(thread, 0.9001, radix));
147 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr5, *resultStr), 0);
148
149 resultStr = factory->NewFromASCII("0.0d384dldb02");
150 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToString(thread, 0.0101, radix));
151 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr6, *resultStr), 0);
152 }
153
154 /**
155 * @tc.name: IsEmptyString
156 * @tc.desc: Check whether the character is empty string through "IsEmptyString" function.
157 * @tc.type: FUNC
158 * @tc.require:
159 */
HWTEST_F_L0(NumberHelperTest,IsEmptyString_001)160 HWTEST_F_L0(NumberHelperTest, IsEmptyString_001)
161 {
162 // 9 ~ 13 and 32 belong to empty string
163 uint8_t a[] = {0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x20};
164 for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
165 EXPECT_TRUE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
166 }
167 }
168
HWTEST_F_L0(NumberHelperTest,IsEmptyString_002)169 HWTEST_F_L0(NumberHelperTest, IsEmptyString_002)
170 {
171 // 14 ~ 31 not belong to empty string
172 uint8_t a[] = {0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
173 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
174 for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
175 EXPECT_FALSE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
176 }
177 }
178
HWTEST_F_L0(NumberHelperTest,IsEmptyString_003)179 HWTEST_F_L0(NumberHelperTest, IsEmptyString_003)
180 {
181 // 0 ~ 8 not belong to empty string
182 uint8_t a[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
183 for (int i = 0; i < static_cast<int>(sizeof(a)); i++) {
184 EXPECT_FALSE(NumberHelper::IsEmptyString(&a[i], &a[i] + 1));
185 }
186 }
187
HWTEST_F_L0(NumberHelperTest,IsEmptyString_004)188 HWTEST_F_L0(NumberHelperTest, IsEmptyString_004)
189 {
190 // 160 belong to empty string
191 uint16_t c = 160;
192 utf_helper::Utf8Char d = utf_helper::ConvertUtf16ToUtf8(c, 0, true);
193 EXPECT_EQ(d.ch.at(1), 160);
194 uint8_t b = d.ch.at(1);
195 EXPECT_TRUE(NumberHelper::IsEmptyString(&b, &b + 1));
196 }
197
198 /**
199 * @tc.name: TruncateDouble
200 * @tc.desc:This function takes the integer part of double type.When it is positive,it is rounded down
201 * When it is negative,it is rounded up.
202 * @tc.type: FUNC
203 * @tc.require:
204 */
HWTEST_F_L0(NumberHelperTest,TruncateDouble)205 HWTEST_F_L0(NumberHelperTest, TruncateDouble)
206 {
207 EXPECT_EQ(NumberHelper::TruncateDouble(NAN_VALUE), 0);
208 EXPECT_EQ(NumberHelper::TruncateDouble(POSITIVE_INFINITY), POSITIVE_INFINITY);
209 // round down
210 EXPECT_EQ(NumberHelper::TruncateDouble(4.1), 4);
211 EXPECT_EQ(NumberHelper::TruncateDouble(4.9), 4);
212 EXPECT_EQ(NumberHelper::TruncateDouble(101.111), 101);
213 EXPECT_EQ(NumberHelper::TruncateDouble(101.999), 101);
214 // round up
215 EXPECT_EQ(NumberHelper::TruncateDouble(-4.1), -4);
216 EXPECT_EQ(NumberHelper::TruncateDouble(-4.9), -4);
217 EXPECT_EQ(NumberHelper::TruncateDouble(-101.111), -101);
218 EXPECT_EQ(NumberHelper::TruncateDouble(-101.999), -101);
219 }
220
221 /**
222 * @tc.name: DoubleToInt
223 * @tc.desc: This function takes the double of integer type.When the decimal part is eight and the number of digits
224 * is 15 ~ 16, add one to convert to integer.According to the binary digits of the integer part,it is divided
225 * into 8, 16 and 64 hexadecimal conversion,for example, 8-hexadecimal conversion.The maximum value of the
226 * integer part is 255. If it exceeds 255,the conversion fails.
227 * @tc.type: FUNC
228 * @tc.require:
229 */
HWTEST_F_L0(NumberHelperTest,DoubleToInt_001)230 HWTEST_F_L0(NumberHelperTest, DoubleToInt_001)
231 {
232 EXPECT_EQ(NumberHelper::DoubleToInt(9.0, INT8_BITS), 9);
233 EXPECT_EQ(NumberHelper::DoubleToInt(9.5555555555555559, INT8_BITS), 9);
234 EXPECT_EQ(NumberHelper::DoubleToInt(9.9999999999999999, INT8_BITS), 10);
235 EXPECT_EQ(NumberHelper::DoubleToInt(128.123456, INT8_BITS), 128);
236 EXPECT_EQ(NumberHelper::DoubleToInt(-128.987654321, INT8_BITS), -128);
237
238 // the exponential bit digits exceeds 7
239 EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT8_BITS), 0);
240 EXPECT_EQ(NumberHelper::DoubleToInt(-256.0, INT8_BITS), 0);
241
242 double nanDouble = 0.0f / 0.0f;
243 EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT8_BITS), 0);
244 double infDouble = POSITIVE_INFINITY;
245 EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT8_BITS), 0);
246 }
247
HWTEST_F_L0(NumberHelperTest,DoubleToInt_002)248 HWTEST_F_L0(NumberHelperTest, DoubleToInt_002)
249 {
250 EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT16_BITS), 256);
251 EXPECT_EQ(NumberHelper::DoubleToInt(256.555555555555556, INT16_BITS), 256);
252 EXPECT_EQ(NumberHelper::DoubleToInt(256.999999999999999, INT16_BITS), 257);
253 EXPECT_EQ(NumberHelper::DoubleToInt(1024.56789, INT16_BITS), 1024);
254 EXPECT_EQ(NumberHelper::DoubleToInt(-1024.987654, INT16_BITS), -1024);
255
256 // the exponential bit digits exceeds 15
257 EXPECT_EQ(NumberHelper::DoubleToInt(65536.0, INT16_BITS), 0);
258 EXPECT_EQ(NumberHelper::DoubleToInt(-65536.0, INT16_BITS), 0);
259
260 double nanDouble = 0.0f / 0.0f;
261 EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT16_BITS), 0);
262 double infDouble = POSITIVE_INFINITY;
263 EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT16_BITS), 0);
264 }
265
HWTEST_F_L0(NumberHelperTest,DoubleToInt_003)266 HWTEST_F_L0(NumberHelperTest, DoubleToInt_003)
267 {
268 EXPECT_EQ(NumberHelper::DoubleToInt(256.0, INT64_BITS), 256);
269 EXPECT_EQ(NumberHelper::DoubleToInt(256.555555555555556, INT64_BITS), 256);
270 EXPECT_EQ(NumberHelper::DoubleToInt(256.999999999999999, INT64_BITS), 257);
271 EXPECT_EQ(NumberHelper::DoubleToInt(65536.55555, INT64_BITS), 65536);
272 EXPECT_EQ(NumberHelper::DoubleToInt(-65536.99999, INT64_BITS), -65536);
273
274 EXPECT_EQ(NumberHelper::DoubleToInt(2147483647.0, INT64_BITS), 2147483647);
275 EXPECT_EQ(NumberHelper::DoubleToInt(-2147483647.0, INT64_BITS), -2147483647);
276
277 double nanDouble = 0.0f / 0.0f;
278 EXPECT_EQ(NumberHelper::DoubleToInt(nanDouble, INT64_BITS), 0);
279 double infDouble = POSITIVE_INFINITY;
280 EXPECT_EQ(NumberHelper::DoubleToInt(infDouble, INT64_BITS), 0);
281 }
282
283 /**
284 * @tc.name: DoubleInRangeInt32
285 * @tc.desc: The function is to convert double type to int type,The maximum value of integer part of double type
286 * cannot exceed the maximum value of int, and the minimum value of integer part cannot exceed the
287 * minimum value of int.
288 * @tc.type: FUNC
289 * @tc.require:
290 */
HWTEST_F_L0(NumberHelperTest,DoubleInRangeInt32)291 HWTEST_F_L0(NumberHelperTest, DoubleInRangeInt32)
292 {
293 // more than INT_MAX
294 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(2147483649.0), 2147483647);
295 // less than INT_MIN
296 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-2147483649.0), -2147483648);
297
298 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(128.0), 128);
299 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-128.999999999999999), -129);
300 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(256.0), 256);
301 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-256.0), -256);
302 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(12345.6789), 12345);
303 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-12345.6789), -12345);
304 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(65535.999999999999999), 65536);
305 EXPECT_EQ(NumberHelper::DoubleInRangeInt32(-65535), -65535);
306 }
307
HWTEST_F_L0(NumberHelperTest,DoubleToExponential)308 HWTEST_F_L0(NumberHelperTest, DoubleToExponential)
309 {
310 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
311 int radix;
312
313 radix = -4;
314 JSHandle<EcmaString> resultStr = factory->NewFromASCII("1.239876e+2");
315 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
316 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr1, *resultStr), 0);
317
318 radix = -6;
319 resultStr = factory->NewFromASCII("1.239876e+2");
320 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToExponential(thread, 123.9876, radix));
321 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr2, *resultStr), 0);
322
323 radix = 2;
324 resultStr = factory->NewFromASCII("1.24e+2");
325 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToExponential(thread, 123.567, radix));
326 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr3, *resultStr), 0);
327
328 radix = 6;
329 resultStr = factory->NewFromASCII("1.234567e+2");
330 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToExponential(thread, 123.4567, radix));
331 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr4, *resultStr), 0);
332
333 radix = 7;
334 resultStr = factory->NewFromASCII("1.2345670e+2");
335 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToExponential(thread, 123.45670, radix));
336 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr5, *resultStr), 0);
337
338 radix = 3;
339 resultStr = factory->NewFromASCII("1.230e+2");
340 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToExponential(thread, 123.0123, radix));
341 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr6, *resultStr), 0);
342 }
343
HWTEST_F_L0(NumberHelperTest,DoubleToFixed)344 HWTEST_F_L0(NumberHelperTest, DoubleToFixed)
345 {
346 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
347 int radix;
348
349 radix = 1;
350 JSHandle<EcmaString> resultStr = factory->NewFromASCII("123.5");
351 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
352 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr1, *resultStr), 0);
353
354 radix = 2;
355 resultStr = factory->NewFromASCII("123.46");
356 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
357 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr2, *resultStr), 0);
358
359 radix = 3;
360 resultStr = factory->NewFromASCII("123.456");
361 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
362 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr3, *resultStr), 0);
363
364 radix = 4;
365 resultStr = factory->NewFromASCII("123.4560");
366 JSHandle<EcmaString> handleEcmaStr4(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
367 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr4, *resultStr), 0);
368
369 radix = 0;
370 resultStr = factory->NewFromASCII("123");
371 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToFixed(thread, 123.456, radix));
372 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr5, *resultStr), 0);
373 }
374
375 /**
376 * @tc.name: DoubleToPrecision
377 * @tc.desc: Convert double decimal type to Precision type through "DoubleToPrecision" function.If the logarithm
378 * of number based on ten is less than zero and radix Digit is more than zero or it is greater than zero
379 * and radix Digit is less than MAX_EXPONENT_DIGIT call the DoubleToFixed function.other call
380 * DoubleToExponential function.
381 * @tc.type: FUNC
382 * @tc.require:
383 */
HWTEST_F_L0(NumberHelperTest,DoubleToPrecision)384 HWTEST_F_L0(NumberHelperTest, DoubleToPrecision)
385 {
386 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
387 int radix;
388
389 radix = 1;
390 JSHandle<EcmaString> resultStr = factory->NewFromASCII("0");
391 JSHandle<EcmaString> handleEcmaStr1(thread, NumberHelper::DoubleToPrecision(thread, 0.0, radix));
392 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr1, *resultStr), 0);
393
394 resultStr = factory->NewFromASCII("0.0001");
395 JSHandle<EcmaString> handleEcmaStr2(thread, NumberHelper::DoubleToPrecision(thread, 0.0001, radix));
396 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr2, *resultStr), 0);
397
398 resultStr = factory->NewFromASCII("1e-7");
399 JSHandle<EcmaString> handleEcmaStr3(thread, NumberHelper::DoubleToPrecision(thread, 0.0000001, radix));
400 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr3, *resultStr), 0);
401
402 resultStr = factory->NewFromASCII("1e+3");
403 JSHandle<EcmaString> handleEcmaStr5(thread, NumberHelper::DoubleToPrecision(thread, 1000.1234, radix));
404 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr5, *resultStr), 0);
405
406 radix = 6;
407 resultStr = factory->NewFromASCII("1000.12");
408 JSHandle<EcmaString> handleEcmaStr6(thread, NumberHelper::DoubleToPrecision(thread, 1000.1234, radix));
409 EXPECT_EQ(EcmaStringAccessor::Compare(*handleEcmaStr6, *resultStr), 0);
410 }
411
412 /**
413 * @tc.name: DoubleToPrecision
414 * @tc.desc: Convert double decimal type to Precision type through "DoubleToPrecision" function.If the logarithm
415 * of number based on ten is less than zero and radix Digit is more than zero or it is greater than zero
416 * and radix Digit is less than MAX_EXPONENT_DIGIT call the DoubleToFixed function.other call
417 * DoubleToExponential function.
418 * @tc.type: FUNC
419 * @tc.require:
420 */
HWTEST_F_L0(NumberHelperTest,StringToDoubleWithRadix)421 HWTEST_F_L0(NumberHelperTest, StringToDoubleWithRadix)
422 {
423 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
424 int radix;
425 Span<const uint8_t> sp;
426 [[maybe_unused]] CVector<uint8_t> buf;
427 JSHandle<EcmaString> resultStr;
428
429 radix = 3;
430 resultStr = factory->NewFromASCII("-12");
431 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
432 // 5 = 1 * 3 + 2
433 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), -5);
434
435 radix = 4;
436 resultStr = factory->NewFromASCII("1234567");
437 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
438 // 27 = (1 * 4 + 2) * 4 + 3
439 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 27);
440 // string has space
441 resultStr = factory->NewFromASCII(" 12345 ");
442 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
443 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 27);
444
445 radix = 16;
446 resultStr = factory->NewFromASCII("0x00ff");
447 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
448 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 255);
449
450 resultStr = factory->NewFromASCII("0x0010");
451 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
452 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 16);
453
454 resultStr = factory->NewFromASCII("0x1234");
455 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
456 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 4660);
457 // string has space
458 resultStr = factory->NewFromASCII(" 0x12 ");
459 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
460 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 18);
461
462 resultStr = factory->NewFromASCII("0x1234XX");
463 sp = EcmaStringAccessor(resultStr).ToUtf8Span(buf);
464 EXPECT_EQ(NumberHelper::StringToDoubleWithRadix(sp.begin(), sp.end(), radix).GetDouble(), 4660);
465 }
466
467 /**
468 * @tc.name: IntToString
469 * @tc.desc: Convert integer type to string type through "IntToString" function.
470 * @tc.type: FUNC
471 * @tc.require:
472 */
HWTEST_F_L0(NumberHelperTest,IntToString)473 HWTEST_F_L0(NumberHelperTest, IntToString)
474 {
475 EXPECT_STREQ(NumberHelper::IntToString(0).c_str(), "0");
476 EXPECT_STREQ(NumberHelper::IntToString(-100).c_str(), "-100");
477 EXPECT_STREQ(NumberHelper::IntToString(123).c_str(), "123");
478 EXPECT_STREQ(NumberHelper::IntToString(1234).c_str(), "1234");
479 }
480
481 /**
482 * @tc.name: IntegerToString
483 * @tc.desc: Convert the decimal number into the hexadecimal number corresponding to Radix and convert it into a string
484 * Check whether the returned string result is the same as the actual conversion result.
485 * @tc.type: FUNC
486 * @tc.require:
487 */
HWTEST_F_L0(NumberHelperTest,IntegerToString)488 HWTEST_F_L0(NumberHelperTest, IntegerToString)
489 {
490 int radix = 2;
491 // number = (radix + 1) * MAX_MANTISSA
492 CString integerStr = NumberHelper::IntegerToString(static_cast<double>((radix + 1) * (0x1ULL << 52U)), radix);
493 EXPECT_STREQ(integerStr.c_str(), "110000000000000000000000000000000000000000000000000000");
494
495 integerStr = NumberHelper::IntegerToString(static_cast<double>(10), radix);
496 EXPECT_STREQ(integerStr.c_str(), "1010");
497
498 radix = 3;
499 integerStr = NumberHelper::IntegerToString(static_cast<double>(33), radix);
500 EXPECT_STREQ(integerStr.c_str(), "1020");
501
502 radix = 8;
503 integerStr = NumberHelper::IntegerToString(static_cast<double>(128), radix);
504 EXPECT_STREQ(integerStr.c_str(), "200");
505
506 integerStr = NumberHelper::IntegerToString(static_cast<double>(128.985), radix);
507 EXPECT_STREQ(integerStr.c_str(), "200");
508
509 radix = 16;
510 integerStr = NumberHelper::IntegerToString(static_cast<double>(256), radix);
511 EXPECT_STREQ(integerStr.c_str(), "100");
512
513 radix = 24;
514 integerStr = NumberHelper::IntegerToString(static_cast<double>(987654), radix);
515 EXPECT_STREQ(integerStr.c_str(), "2nag6");
516
517 integerStr = NumberHelper::IntegerToString(static_cast<double>(23), radix);
518 EXPECT_STREQ(integerStr.c_str(), "n");
519 }
520
521 /**
522 * @tc.name: NumberToString
523 * @tc.desc: The abstract operation NumberToString converts a Number m to String format
524 * @tc.type: FUNC
525 * @tc.require:
526 */
HWTEST_F_L0(NumberHelperTest,NumberToString)527 HWTEST_F_L0(NumberHelperTest, NumberToString)
528 {
529 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
530 double d = 8.1999999999999993;
531 JSHandle<EcmaString> result = NumberHelper::NumberToString(thread, JSTaggedValue(d));
532 JSHandle<EcmaString> target = factory->NewFromASCII("8.2");
533 EXPECT_EQ(EcmaStringAccessor::Compare(*result, *target), 0);
534
535 double d2 = 0.30000000000000004;
536 JSHandle<EcmaString> result1 = NumberHelper::NumberToString(thread, JSTaggedValue(d2));
537 JSHandle<EcmaString> target1 = factory->NewFromASCII("0.30000000000000004");
538 EXPECT_EQ(EcmaStringAccessor::Compare(*result1, *target1), 0);
539 }
540
541 /**
542 * @tc.name: DoubleToInt64
543 * @tc.desc: The abstract operation DoubleToInt64 converts a double value to int64_t
544 * @tc.type: FUNC
545 * @tc.require:
546 */
HWTEST_F_L0(NumberHelperTest,DoubleToInt64)547 HWTEST_F_L0(NumberHelperTest, DoubleToInt64)
548 {
549 int64_t d = NumberHelper::DoubleToInt64(std::numeric_limits<double>::max());
550 EXPECT_EQ(d, std::numeric_limits<int64_t>::max());
551
552 int64_t d1 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()));
553 EXPECT_EQ(d1, std::numeric_limits<int64_t>::max());
554 int64_t d2 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()));
555 EXPECT_EQ(d2, std::numeric_limits<int64_t>::min());
556
557 int64_t d3 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::max()) + 1);
558 EXPECT_EQ(d3, std::numeric_limits<int64_t>::max());
559 int64_t d4 = NumberHelper::DoubleToInt64(static_cast<double>(std::numeric_limits<int64_t>::min()) - 1);
560 EXPECT_EQ(d4, std::numeric_limits<int64_t>::min());
561
562 int64_t d5 = NumberHelper::DoubleToInt64(0);
563 EXPECT_EQ(d5, 0);
564 }
565 } // namespace panda::ecmascript