Странное поведение при преобразовании строк C в/из doubles

Мне трудно понять правила C о том, какую точность предполагать при печати двойников или при преобразовании строк в двойные. Следующая программа должна проиллюстрировать мою точку зрения:

#include <errno.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
    double x, y;
    const char *s = "1e-310";

    /* Should print zero */
    x = DBL_MIN/100.;
    printf("DBL_MIN = %e, x = %e\n", DBL_MIN, x);

    /* Trying to read in floating point number smaller than DBL_MIN gives an error */
    y = strtod(s, NULL);
    if(errno != 0)
        printf("  Error converting '%s': %s\n", s, strerror(errno));
    printf("y = %e\n", y);

    return 0;
}

Результат, который я получаю при компиляции и запуске этой программы (на Core 2 Duo с gcc 4.5.2):

DBL_MIN = 2.225074e-308, x = 2.225074e-310
  Error converting '1e-310': Numerical result out of range
y = 1.000000e-310

Мои вопросы:

  1. Почему x печатается как ненулевое число? Я знаю, что компиляторы иногда продвигают двойные типы к более высокоточным типам для целей вычислений, но разве printf не должен рассматривать x как 64-битный двойник?
  2. Если библиотека C тайно использует числа с плавающей запятой с расширенной точностью, почему strtod устанавливает errno при попытке преобразовать эти небольшие числа? И почему это все равно дает правильный результат?
  3. Является ли такое поведение просто ошибкой,результат моего конкретного оборудования и среды разработки? (К сожалению, в настоящее время я не могу тестировать на других платформах.)

Спасибо за любую помощь, которую вы можете оказать. Я постараюсь прояснить вопрос по мере получения обратной связи.

7
задан Jordan Carlson 9 January 2012 в 20:14
поделиться