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