• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 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 <locale.h>
17 #include <stdlib.h>
18 #include <math.h>
19 #include <float.h>
20 #include <string.h>
21 #include "functionalext.h"
22 
23 
24 #define EXPECT_DOUBLE_EQ(a, b)                                             \
25     do {                                                                   \
26         if (!(a == b || (fabs(a - b) < DBL_EPSILON)))                      \
27             t_error("%s failed: %f is not equal to %f\n", __func__, a, b); \
28     } while (0)
29 
30 
31 #define LENGTH(x) (sizeof(x) / sizeof *(x))
32 
33 static struct {
34     char *s;
35     double f;
36 } g_t[] = {
37     {"0", 0.0},
38     {"00.00", 0.0},
39     {"-.00000", -0.0},
40     {"1e+1000000", INFINITY},
41     {"1e-1000000", 0},
42     // 2^-1074 * 0.5 - eps
43     {".2470328229206232720882843964341106861825299013071623822127928412503377536351043e-323", 0},
44     // 2^-1074 * 0.5 + eps
45     {".2470328229206232720882843964341106861825299013071623822127928412503377536351044e-323", 0x1p-1074},
46     // 2^-1074 * 1.5 - eps
47     {".7410984687618698162648531893023320585475897039214871466383785237510132609053131e-323", 0x1p-1074},
48     // 2^-1074 * 1.5 + eps
49     {".7410984687618698162648531893023320585475897039214871466383785237510132609053132e-323", 0x1p-1073},
50     // 2^-1022 + 2^-1075 - eps
51     {".2225073858507201630123055637955676152503612414573018013083228724049586647606759e-307", 0x1p-1022},
52     // 2^-1022 + 2^-1075 + eps
53     {".2225073858507201630123055637955676152503612414573018013083228724049586647606760e-307", 0x1.0000000000001p-1022},
54     // 2^1024 - 2^970 - eps
55     {"17976931348623158079372897140530341507993413271003782693617377898044"
56     "49682927647509466490179775872070963302864166928879109465555478519404"
57     "02630657488671505820681908902000708383676273854845817711531764475730"
58     "27006985557136695962284291481986083493647529271907416844436551070434"
59     "2711559699508093042880177904174497791.999999999999999999999999999999", 0x1.fffffffffffffp1023},
60     // 2^1024 - 2^970
61     {"17976931348623158079372897140530341507993413271003782693617377898044"
62     "49682927647509466490179775872070963302864166928879109465555478519404"
63     "02630657488671505820681908902000708383676273854845817711531764475730"
64     "27006985557136695962284291481986083493647529271907416844436551070434"
65     "2711559699508093042880177904174497792", INFINITY},
66     // some random numbers
67     {".5961860348131807091861002266453941950428e00", 0.59618603481318067}, // 0x1.313f4bc3b584cp-1
68     {"1.815013169218038729887460898733526957442e-1", 0.18150131692180388}, // 0x1.73b6f662e1712p-3
69     {"42.07082357534453600681618685682257590772e-2", 0.42070823575344535}, // 0x1.aece23c6e028dp-2
70     {"665.4686306516261456328973225579833470816e-3", 0.66546863065162609}, // 0x1.54b84dea53453p-1
71     {"6101.852922970868621786690495485449831753e-4", 0.61018529229708685}, // 0x1.386a34e5d516bp-1
72     {"76966.95208236968077849464348875471158549e-5", 0.76966952082369677}, // 0x1.8a121f9954dfap-1
73     {"250506.5322228682496132604807222923702304e-6", 0.25050653222286823}, // 0x1.0084c8cd538c2p-2
74     {"2740037.230228005325852424697698331177377e-7", 0.27400372302280052}, // 0x1.18946e9575ef4p-2
75     {"20723093.50049742645941529268715428324490e-8", 0.20723093500497428}, // 0x1.a868b14486e4dp-3
76     {"0.7900280238081604956226011047460238748912e1", 7.9002802380816046}, // 0x1.f99e3100f2eaep+2
77     {"0.9822860653737296848190558448760465863597e2", 98.228606537372968}, // 0x1.88ea17d506accp+6
78     {"0.7468949723190370809405570560160405324869e3", 746.89497231903704}, // 0x1.75728e73f48b7p+9
79     {"0.1630268320282728475980459844271031751665e4", 1630.2683202827284}, // 0x1.97912c28d5cbp+10
80     {"0.4637168629719170695109918769645492022088e5", 46371.686297191707}, // 0x1.6a475f6258737p+15
81     {"0.6537805944497711554209461686415872067523e6", 653780.59444977110}, // 0x1.3f3a9305bb86cp+19
82     {"0.2346324356502437045212230713960457676531e6", 234632.43565024371}, // 0x1.ca4437c3631eap+17
83     {"0.9709481716420048341897258980454298205278e8", 97094817.164200485}, // 0x1.7263284a8242cp+26
84     {"0.4996908522051874110779982354932499499602e9", 499690852.20518744}, // 0x1.dc8ad6434872ap+28
85 };
86 
87 /**
88  * @tc.name      : strtod_l_0100
89  * @tc.desc      : set locale as zh_CN.UTF-8, do basic tests for strtod_l
90  * @tc.level     : Level 0
91  */
strtod_l_0100(void)92 void strtod_l_0100(void)
93 {
94     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN.UTF-8", NULL);
95     int i;
96     double x;
97     char *p;
98 
99     for (i = 0; i < LENGTH(g_t); i++) {
100         x = strtod_l(g_t[i].s, &p, loc);
101         EXPECT_DOUBLE_EQ(x, g_t[i].f);
102     }
103 }
104 
105 
106 /**
107  * @tc.name      : strtod_l_0200
108  * @tc.desc      : set locale as zh_CN, transfer string 123.45xxx to double, and check rest string
109  * @tc.level     : Level 0
110  */
strtod_l_0200(void)111 void strtod_l_0200(void)
112 {
113     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
114     char* str = "123.45xxx";
115     const double target = 123.45;
116     char str1[] = "xxx";
117     char* end;
118     double num = strtod_l(str, &end, loc);
119     EXPECT_DOUBLE_EQ(num, target);
120     if (strcmp(end, str1)) {
121         t_error("%s the result of comparing two strings should be equal", __func__);
122     }
123 }
124 
125 /**
126  * @tc.name      : strtod_l_0300
127  * @tc.desc      : set locale as zh_CN, transfer string +123.45xxx to double, and check rest string
128  * @tc.level     : Level 0
129  */
strtod_l_0300(void)130 void strtod_l_0300(void)
131 {
132     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
133     char* str = "+123.45xxx";
134     const double target = 123.45;
135     char str1[] = "xxx";
136     char* end;
137     double num = strtod_l(str, &end, loc);
138     EXPECT_DOUBLE_EQ(num, target);
139     if (strcmp(end, str1)) {
140         t_error("%s the result of comparing two strings should be equal", __func__);
141     }
142 }
143 
144 /**
145  * @tc.name      : strtod_l_0400
146  * @tc.desc      : set locale as zh_CN, transfer string -123.45xxx to double, and check rest string
147  * @tc.level     : Level 0
148  */
strtod_l_0400(void)149 void strtod_l_0400(void)
150 {
151     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
152     char* str = "-123.45xxx";
153     const double target = -123.45;
154     char str1[] = "xxx";
155     char* end;
156     double num = strtod_l(str, &end, loc);
157     EXPECT_DOUBLE_EQ(num, target);
158     if (strcmp(end, str1)) {
159         t_error("%s the result of comparing two strings should be equal", __func__);
160     }
161 }
162 
163 /**
164  * @tc.name      : strtod_l_0500
165  * @tc.desc      : set locale as zh_CN, transfer string   123.45xxx to double, and check rest string
166  * @tc.level     : Level 0
167  */
strtod_l_0500(void)168 void strtod_l_0500(void)
169 {
170     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
171     char* str = "  123.45xxx";
172     const double target = 123.45;
173     char str1[] = "xxx";
174     char* end;
175     double num = strtod_l(str, &end, loc);
176     EXPECT_DOUBLE_EQ(num, target);
177     if (strcmp(end, str1)) {
178         t_error("%s the result of comparing two strings should be equal", __func__);
179     }
180 }
181 
182 /**
183  * @tc.name      : strtod_l_0600
184  * @tc.desc      : set locale as zh_CN, transfer string   123.45xxx to double, and check rest string
185  * @tc.level     : Level 0
186  */
strtod_l_0600(void)187 void strtod_l_0600(void)
188 {
189     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
190     char* str = "xxx123.45";
191     const double target = 0;
192     char str1[] = "xxx123.45";
193     char* end;
194     double num = strtod_l(str, &end, loc);
195     EXPECT_DOUBLE_EQ(num, target);
196     if (strcmp(end, str1)) {
197         t_error("%s the result of comparing two strings should be equal", __func__);
198     }
199 }
200 
201 /**
202  * @tc.name      : strtod_l_0700
203  * @tc.desc      : set locale as zh_CN, transfer string +inf to double
204  * @tc.level     : Level 0
205  */
strtod_l_0700(void)206 void strtod_l_0700(void)
207 {
208     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
209     char* str = "+inf";
210     const double target = INFINITY;
211     char* end;
212     double num = strtod_l(str, &end, loc);
213     EXPECT_DOUBLE_EQ(num, target);
214 }
215 
216 /**
217  * @tc.name      : strtod_l_0800
218  * @tc.desc      : set locale as zh_CN, transfer string infinity to double
219  * @tc.level     : Level 0
220  */
strtod_l_0800(void)221 void strtod_l_0800(void)
222 {
223     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
224     char* str = "infinity";
225     const double target = INFINITY;
226     char* end;
227     double num = strtod_l(str, &end, loc);
228     EXPECT_DOUBLE_EQ(num, target);
229 }
230 
231 /**
232  * @tc.name      : strtod_l_0900
233  * @tc.desc      : set locale as zh_CN, transfer string infinixxx to double, and check rest string
234  * @tc.level     : Level 0
235  */
strtod_l_0900(void)236 void strtod_l_0900(void)
237 {
238     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
239     char* str = "infinixxx";
240     const double target = INFINITY;
241     char str1[] = "inixxx";
242     char* end;
243     double num = strtod_l(str, &end, loc);
244     EXPECT_DOUBLE_EQ(num, target);
245     if (strcmp(end, str1)) {
246         t_error("%s the result of comparing two strings should be equal", __func__);
247     }
248 }
249 
250 /**
251  * @tc.name      : strtod_l_1000
252  * @tc.desc      : set locale as zh_CN, transfer string -inf to double
253  * @tc.level     : Level 0
254  */
strtod_l_1000(void)255 void strtod_l_1000(void)
256 {
257     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
258     char* str = "-inf";
259     const double target = -INFINITY;
260     char* end;
261     double num = strtod_l(str, &end, loc);
262     EXPECT_DOUBLE_EQ(num, target);
263 }
264 
265 /**
266  * @tc.name      : strtod_l_1100
267  * @tc.desc      : set locale as zh_CN, transfer string +nan to double
268  * @tc.level     : Level 0
269  */
strtod_l_1100(void)270 void strtod_l_1100(void)
271 {
272     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
273     char* str = "+nan";
274     const double target = NAN;
275     char* end;
276     double num = strtod_l(str, &end, loc);
277     if (!isnan(num)) {
278         t_error("%s failed: res should be nan\n", __func__);
279     }
280 }
281 
282 /**
283  * @tc.name      : strtod_l_1200
284  * @tc.desc      : set locale as zh_CN, transfer string -nan to double
285  * @tc.level     : Level 0
286  */
strtod_l_1200(void)287 void strtod_l_1200(void)
288 {
289     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
290     char* str = "-nan";
291     const double target = NAN;
292     char* end;
293     double num = strtod_l(str, &end, loc);
294     if (!isnan(num)) {
295         t_error("%s failed: res should be nan\n", __func__);
296     }
297 }
298 
299 /**
300  * @tc.name      : strtod_l_1300
301  * @tc.desc      : set locale as zh_CN, transfer string 0X1.BC to double, and check rest string
302  * tips: strtod_l does not support hexadecimal number, should return 0
303  * @tc.level     : Level 0
304  */
strtod_l_1300(void)305 void strtod_l_1300(void)
306 {
307     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
308     char* str = "0X1.BC";
309     const double target = 0;
310     char str1[] = "X1.BC";
311     char* end;
312     double num = strtod_l(str, &end, loc);
313     EXPECT_DOUBLE_EQ(num, target);
314     if (strcmp(end, str1)) {
315         t_error("%s the result of comparing two strings should be equal", __func__);
316     }
317 }
318 
319 /**
320  * @tc.name      : strtod_l_1400
321  * @tc.desc      : set locale as zh_CN, transfer empty string, the res should be zero
322  * @tc.level     : Level 0
323  */
strtod_l_1400(void)324 void strtod_l_1400(void)
325 {
326     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
327     char* str = "";
328     const double target = 0;
329     char* end;
330     double num = strtod_l(str, &end, loc);
331     EXPECT_DOUBLE_EQ(num, target);
332 }
333 
334 /**
335  * @tc.name      : strtod_l_1500
336  * @tc.desc      : set locale as zh_CN, transfer string    xxx to num, the res should be zero
337  * @tc.level     : Level 0
338  */
strtod_l_1500(void)339 void strtod_l_1500(void)
340 {
341     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN", NULL);
342     char* str = "   xxx";
343     const double target = 0;
344     char str1[] = "   xxx";
345     char* end;
346     double num = strtod_l(str, &end, loc);
347     EXPECT_DOUBLE_EQ(num, target);
348     if (strcmp(end, str1)) {
349         t_error("%s the result of comparing two strings should be equal", __func__);
350     }
351 }
352 
353 
354 /**
355  * @tc.name      : strtod_l_1600
356  * @tc.desc      : set locale as de_DE whcih is not supported by newlocale, transfer string 1234.56 to num,
357  the string should be processed by original strtod
358  * @tc.level     : Level 0
359  */
strtod_l_1600(void)360 void strtod_l_1600(void)
361 {
362     locale_t loc = newlocale(LC_ALL_MASK, "de_DE", NULL);
363     char* str = "1234.56";
364     const double target = 1234.56;
365     char str1[] = "";
366     char* end;
367     double num = strtod_l(str, &end, loc);
368     EXPECT_DOUBLE_EQ(num, target);
369     if (strcmp(end, str1)) {
370         t_error("%s the result of comparing two strings should be equal", __func__);
371     }
372 }
373 
374 /**
375  * @tc.name      : strtod_l_1700
376  * @tc.desc      : set locale LC_CTYPE_MASK as zh_CN, transfer blank string to num
377  * @tc.level     : Level 0
378  */
strtod_l_1700(void)379 void strtod_l_1700(void)
380 {
381     locale_t loc = newlocale(LC_CTYPE_MASK, "zh_CN", NULL);
382     char* str = "     ";
383     const double target = 0;
384     char str1[] = "     ";
385     char* end;
386     double num = strtod_l(str, &end, loc);
387     EXPECT_DOUBLE_EQ(num, target);
388     if (strcmp(end, str1)) {
389         t_error("%s the result of comparing two strings should be equal", __func__);
390     }
391 }
392 
393 /**
394  * @tc.name      : strtod_l_1800
395  * @tc.desc      : set locale as zh_CN.UTF-8, set endptr as NULL
396  * @tc.level     : Level 0
397  */
strtod_l_1800(void)398 void strtod_l_1800(void)
399 {
400     locale_t loc = newlocale(LC_ALL_MASK, "zh_CN.UTF-8", NULL);
401     char* str = "123.45";
402     const double target = 123.45;
403     double num = strtod_l(str, NULL, loc);
404     EXPECT_DOUBLE_EQ(num, target);
405 }
406 
main(void)407 int main(void)
408 {
409     strtod_l_0100();
410     strtod_l_0200();
411     strtod_l_0300();
412     strtod_l_0400();
413     strtod_l_0500();
414     strtod_l_0600();
415     strtod_l_0700();
416     strtod_l_0800();
417     strtod_l_0900();
418     strtod_l_1000();
419     strtod_l_1100();
420     strtod_l_1200();
421     strtod_l_1300();
422     strtod_l_1400();
423     strtod_l_1500();
424     strtod_l_1600();
425     strtod_l_1700();
426     strtod_l_1800();
427 
428     return t_status;
429 }