This program calls strtod() on the first command line argument and prints the returned value:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>
int main(int argc, char **argv)
{
errno = 0;
double d = strtod(argv[1], NULL);
int errno_sav = errno;
printf("string = %s\n", argv[1]);
printf("d = %.*e = %a\n", DBL_DIG + 2, d, d);
printf("errno = %d\n", errno_sav);
printf("DBL_MIN = %.*e = %a\n", DBL_DIG + 2, DBL_MIN, DBL_MIN);
return 0;
}
When I run it on SUSE Linux Enterprise Server 11 SP2 or Linux Mint 17 Qiana with an argument of 2.22507385850720138309e-308
, corresponding to the smallest representable1 double value (DBL_MIN), it gives the output I expect:
string = 2.22507385850720138309e-308
d = 2.22507385850720138e-308 = 0x1p-1022
errno = 0
DBL_MIN = 2.22507385850720138e-308 = 0x1p-1022
However, on SUSE Linux Enterprise Server 11 SP3 with the same argument2, errno is set to ERANGE:
string = 2.22507385850720138309e-308
d = 2.22507385850720138e-308 = 0x1p-1022
errno = 34
DBL_MIN = 2.22507385850720138e-308 = 0x1p-1022
Is the second behaviour valid, and if so why?
Footnotes:
Since DBL_MIN is representable I think this question is different from "Odd behavior when converting C strings to/from doubles" where the value converted had underflowed.
On SUSE if I run the program with an argument of
2.22507385850720138310e-308
then errno is set to 0. (And if I run the program with an argument of0x1p-1022
then errno is also set to 0.)