Эта программа вызывает strtod() на первый аргументе командной строки и выводит возвращаемое значение:Почему strtod() с DBL_MIN дает ERANGE?
#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;
}
Когда я запускаю его на SUSE Linux Enterprise Server 11 SP2 или Linux Mint 17 Qiana с аргументом 2.22507385850720138309e-308
, соответствующей к маленьким представимому двойное значение (DBL_MIN), он дает выход я ожидаю:
string = 2.22507385850720138309e-308
d = 2.22507385850720138e-308 = 0x1p-1022
errno = 0
DBL_MIN = 2.22507385850720138e-308 = 0x1p-1022
Однако на SUSE Linux Enterprise Server 11 SP3 с тем же аргументом , эээ нет установлен в ERANGE:
string = 2.22507385850720138309e-308
d = 2.22507385850720138e-308 = 0x1p-1022
errno = 34
DBL_MIN = 2.22507385850720138e-308 = 0x1p-1022
ли второе поведение в силе, и если да, то почему?
Сноска:
С DBL_MIN представим Я думаю, этот вопрос отличается от "Odd behavior when converting C strings to/from doubles", где значение конвертируется было underflowed.
На SUSE, если я запустить программу с аргументом
2.22507385850720138310e-308
затем ERRNO устанавливается в 0. (А если я запустить программу с аргументом0x1p-1022
затем ERRNO также устанавливается в 0.)
Вместо 'printf (" d =% e \ n ", d);', используйте 'printf (" d =%. * E \ n ", DBL_DIG + 2, d);' для отображения 'd' до достаточной точности. Может также хотеть использовать 'printf (" d =% a \ n ", d);' для точного вывода. – chux
Обе системы '2.22507385850720138e-308'. Я изменю программу, чтобы показать их. –
Обратите внимание, что ваш номер входа, конечно, * не * точно представлен, как можно быстро определить. При условии, что правильная доля больше нуля и с конечным двоичным представлением, десятичное представление этой фракции также является конечным, а наименьшая значимая ненулевая цифра его десятичного представления равна 5. Поскольку наименьшая значащая десятичная цифра * вашего * число равно 9 (и это находится во дробной части числа), дробная часть и, следовательно, целое число, не имеет конечного двоичного представления. –