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