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




Reply via email to