On Wed, 28 Jul 2021, Piotr Caban wrote:
Hi Martin,
On 7/28/21 12:44 AM, Martin Storsjo wrote:
float CDECL _strtof_l( const char *str, char **end, _locale_t locale ) {
- return _strtod_l(str, end, locale);
- double ret = _strtod_l(str, end, locale);
- if (isfinite(ret)) {
/* Check for cases that aren't out of range for doubles, but that
are
* for floats. */
if (ret > FLT_MAX)
*_errno() = ERANGE;
else if (ret < -FLT_MAX)
*_errno() = ERANGE;
else if (ret > 0 && ret < FLT_MIN)
*_errno() = ERANGE;
else if (ret < 0 && ret > -FLT_MIN)
*_errno() = ERANGE;
- }
- return ret;
It doesn't work for denormals (e.g. for "1.4e-45" input string).
Hmm, right... When I studied this aspect for mingw-w64, I noted that different CRTs seem to differ in what they do for denormals in strtod/strtof; some set ERANGE, some don't. But you're right that ucrtbase doesn't seem to set it for these denormals, so we shouldn't either.
Maybe something along this lines will work better: if (ret && isfinite(ret)) { float f = ret; if (!f || !isfinite(f)) *_errno() = ERANGE; }
Thanks! That does seem to work. I'll amend the patch to include testcases for 0 too, in addition to denormals.
// Martin