ok = false;
else
{
- /* Allow underflow (in which case CONVERT returns zero),
- but flag overflow as an error. The user can decide
- to use the limits in RESULT upon ERANGE. */
+ /* Flag overflow as an error.
+ Flag gradual underflow as an error.
+ Flag flush-to-zero underflow as no error.
+ In either case, the caller can inspect *RESULT to get more details. */
if (val != 0 && errno == ERANGE)
ok = false;
}
if (ptr != NULL)
*ptr = terminator;
+ /* Callers rely on *RESULT even when !ok. */
*result = val;
+
return ok;
}
#endif
+/* Converts the initial portion of the string starting at STR (if PTR != NULL)
+ or the entire string starting at STR (if PTR == NULL) to a number of type
+ 'double'.
+ CONVERT should be a conversion function with the same calling conventions
+ as strtod, such as strtod or c_strtod.
+ If successful, it returns true, with *RESULT set to the result.
+ If it fails, it returns false, with *RESULT and errno set.
+ In total, there are the following cases:
+
+ Condition RET *RESULT errno
+ -----------------------------------------------------------------------------
+ conversion error: no number parsed false 0.0 EINVAL or 0
+ PTR == NULL, number parsed but junk after number false value 0
+ NaN true NaN 0
+ ±Infinity true ±HUGE_VAL 0
+ overflow false ±HUGE_VAL ERANGE
+ gradual underflow [!MSVC] false near zero ERANGE
+ gradual underflow [MSVC] true near zero 0
+ flush-to-zero underflow true ±0.0 ERANGE
+ other finite value true value 0
+
+ In both cases, if PTR != NULL, *PTR is set to point to the character after
+ the parsed number. */
bool xstrtod (const char *str, const char **ptr, double *result,
double (*convert) (char const *, char **));
+
+/* Converts the initial portion of the string starting at STR (if PTR != NULL)
+ or the entire string starting at STR (if PTR == NULL) to a number of type
+ 'long double'.
+ CONVERT should be a conversion function with the same calling conventions
+ as strtold, such as strtold or c_strtold.
+ If successful, it returns true, with *RESULT set to the result.
+ If it fails, it returns false, with *RESULT and errno set.
+ In total, there are the following cases:
+
+ Condition RET *RESULT errno
+ -----------------------------------------------------------------------------
+ conversion error: no number parsed false 0.0L EINVAL or 0
+ PTR == NULL, number parsed but junk after number false value 0
+ NaN true NaN 0
+ ±Infinity true ±HUGE_VALL 0
+ overflow false ±HUGE_VALL ERANGE
+ gradual underflow [!MSVC] false near zero ERANGE
+ gradual underflow [MSVC] true near zero 0
+ flush-to-zero underflow true ±0.0L ERANGE
+ other finite value true value 0
+
+ In both cases, if PTR != NULL, *PTR is set to point to the character after
+ the parsed number. */
bool xstrtold (const char *str, const char **ptr, long double *result,
long double (*convert) (char const *, char **));