xref: /reactos/sdk/lib/ucrt/convert/strtod.cpp (revision fe11f7a2)
1 //
2 // strtod.cpp
3 //
4 //      Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // Definitions of the functions that convert strings to floating point numbers.
7 // These functions, the strtox and wcstox functions for floating point types,
8 // recogize an optional sequence of tabs and space, then an optional sign, then
9 // a sequence of digits optionally containing a decimal point, then an optional
10 // e or E followed by an optionally signed integer, and converts all of this to
11 // a floating point number.  The first unrecognized character ends the string.
12 // The *end_ptr pointer is updated to point to the last character of the string
13 //
14 #define _ALLOW_OLD_VALIDATE_MACROS
15 #include <corecrt_internal_strtox.h>
16 #include <stdlib.h>
17 
18 
19 
20 template <typename FloatingType, typename Character>
21 static FloatingType __cdecl common_strtod_l(
22     _In_z_                      Character const*    const   string,
23     _Out_opt_ _Deref_post_z_    Character**         const   end_ptr,
24                                 _locale_t           const   locale
25     ) throw()
26 {
27     if (end_ptr)
28     {
29         *end_ptr = const_cast<Character*>(string);
30     }
31 
32     _VALIDATE_RETURN(string != nullptr, EINVAL, 0.0);
33 
34     _LocaleUpdate locale_update(locale);
35 
36     FloatingType result{};
37     SLD_STATUS const status = __crt_strtox::parse_floating_point(
38         locale_update.GetLocaleT(),
39         __crt_strtox::make_c_string_character_source(string, end_ptr),
40         &result);
41 
42     if (status == SLD_OVERFLOW || status == SLD_UNDERFLOW)
43     {
44         errno = ERANGE;
45     }
46 
47     return result;
48 }
49 
50 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 //
52 // Narrow Strings => Floating Point
53 //
54 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 extern "C" float __cdecl strtof(
56     char const* const string,
57     char**      const end_ptr
58     )
59 {
60     return common_strtod_l<float>(string, end_ptr, nullptr);
61 }
62 
63 extern "C" float __cdecl _strtof_l(
64     char const* const string,
65     char**      const end_ptr,
66     _locale_t   const locale
67     )
68 {
69     return common_strtod_l<float>(string, end_ptr, locale);
70 }
71 
72 extern "C" double __cdecl strtod(
73     char const* const string,
74     char**      const end_ptr
75     )
76 {
77     return common_strtod_l<double>(string, end_ptr, nullptr);
78 }
79 
80 extern "C" double __cdecl _strtod_l(
81     char const* const string,
82     char**      const end_ptr,
83     _locale_t   const locale
84     )
85 {
86     return common_strtod_l<double>(string, end_ptr, locale);
87 }
88 
89 extern "C" long double __cdecl strtold(
90     char const* const string,
91     char**      const end_ptr
92     )
93 {
94     return common_strtod_l<double>(string, end_ptr, nullptr);
95 }
96 
97 
98 extern "C" long double __cdecl _strtold_l(
99     char const* const string,
100     char**      const end_ptr,
101     _locale_t   const locale
102     )
103 {
104     return common_strtod_l<double>(string, end_ptr, locale);
105 }
106 
107 
108 
109 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110 //
111 // Wide Strings => Floating Point
112 //
113 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
114 extern "C" float __cdecl wcstof(
115     wchar_t const* const string,
116     wchar_t**      const end_ptr
117     )
118 {
119     return common_strtod_l<float>(string, end_ptr, nullptr);
120 }
121 
122 extern "C" float __cdecl _wcstof_l(
123     wchar_t const* const string,
124     wchar_t**      const end_ptr,
125     _locale_t      const locale
126     )
127 {
128     return common_strtod_l<float>(string, end_ptr, locale);
129 }
130 
131 extern "C" double __cdecl wcstod(
132     wchar_t const* const string,
133     wchar_t**      const end_ptr
134     )
135 {
136     return common_strtod_l<double>(string, end_ptr, nullptr);
137 }
138 
139 extern "C" double __cdecl _wcstod_l(
140     wchar_t const* const string,
141     wchar_t**      const end_ptr,
142     _locale_t      const locale
143     )
144 {
145     return common_strtod_l<double>(string, end_ptr, locale);
146 }
147 
148 extern "C" long double __cdecl wcstold(
149     wchar_t const* const string,
150     wchar_t**      const end_ptr
151     )
152 {
153     return common_strtod_l<double>(string, end_ptr, nullptr);
154 }
155 
156 
157 extern "C" long double __cdecl _wcstold_l(
158     wchar_t const* const string,
159     wchar_t**      const end_ptr,
160     _locale_t      const locale
161     )
162 {
163     return common_strtod_l<double>(string, end_ptr, locale);
164 }
165