Hi, In the current behaviour of xstrtod:
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 the behaviour upon gradual underflow does not make sense to me: * It is platform-dependent: on MSVC gradual underflow is seen as "normal" or successful, on other platforms as an error. * On platforms other than MSVC: 1.0 -> ret = true, *result = 1.0 1e-320 -> ret = false, *result = 1e-320 (approx.) 1e-500 -> ret = true, *result = 0.0 That is, a reduced accuracy of the result (in gradual underflow) is reported as a failure, but a completely removed accuracy of the result (in flush-to-zero underflow) is reported as success. I propose to change the gradual underflow behaviour of xstrtod so that the above table becomes: 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 true near zero 0 flush-to-zero underflow true ±0.0 ERANGE other finite value true value 0 and similarly for xstrtold. coreutils' 'sleep' and 'timeout' would be unaffected, because they treat overflow and underflow as success anyway: xstrtod (argv[i], &p, &s, cl_strtod) || errno == ERANGE The effect on coreutils' 'tail' would be that in $ tail -f -s 1.0 /dev/null <succeeds> $ tail -f -s 0.000001 /dev/null <succeeds> $ tail -f -s 1e-300 /dev/null <succeeds> $ tail -f -s 1e-320 /dev/null tail: invalid number of seconds: ‘1e-320’ $ tail -f -s 1e-400 /dev/null <succeeds> the error in the 1e-320 case goes away. That is, that 1e-320 behaves like 1e-300 and 1e-400. Objections? ------------------------------------------------------------------- I do *not* propose to change the *overflow* behaviour, because I think that overflow handling should better be handled by the caller. $ tail -f -s 1e300 /dev/null <succeeds> $ tail -f -s 1e500 /dev/null tail: invalid number of seconds: ‘1e500’ $ tail -f -s infinity /dev/null <succeeds> Here, the caller should probably test isfinite() of the result, or use || errno == ERANGE like the other two programs. Bruno