Как бесконечность представлена ​​в C двойном?

Я узнал из книгиКомпьютерные системы: взгляд программиста что стандарт IEEE требует представления числа с плавающей запятой двойной точности в следующем 64-битном двоичном формате:

s: 1 бит для знакаexp: 11 бит для показателя степениГРП: 52 бита для дроби

+ Бесконечность представляется как специальное значение со следующим шаблоном:

с = 0все биты опыта 1все биты дроби равны 0

И я думаю, что полная 64-битная для double должна быть в следующем порядке:

(Ы) (ехр) (ГРП)

Поэтому я пишу следующий код C, чтобы проверить это:

//Check the infinity
double x1 = (double)0x7ff0000000000000;  // This should be the +infinity
double x2 = (double)0x7ff0000000000001; //  Note the extra ending 1, x2 should be NaN
printf("\nx1 = %f, x2 = %f sizeof(double) = %d", x1,x2, sizeof(x2));
if (x1 == x2)
    printf("\nx1 == x2");
else
    printf("\nx1 != x2");

Но результат:

x1 = 9218868437227405300.000000, x2 = 9218868437227405300.000000 sizeof(double) = 8
x1 == x2

Почему число является действительным числом, а не ошибкой бесконечности?

Почему х1 == х2?

(Я использую компилятор MinGW GCC.)

ДОБАВИТЬ 1

Я изменил код, как показано ниже, и успешно проверил Infinity и NaN.

//Check the infinity and NaN
unsigned long long x1 = 0x7ff0000000000000ULL; // +infinity as double
unsigned long long x2 = 0xfff0000000000000ULL; // -infinity as double
unsigned long long x3 = 0x7ff0000000000001ULL; // NaN as double
double y1 =* ((double *)(&x1));
double y2 =* ((double *)(&x2));
double y3 =* ((double *)(&x3));

printf("\nsizeof(long long) = %d", sizeof(x1));
printf("\nx1 = %f, x2 = %f, x3 = %f", x1, x2, x3); // %f is good enough for output
printf("\ny1 = %f, y2 = %f, y3 = %f", y1, y2, y3);

Результат:

sizeof(long long) = 8
x1 = 1.#INF00, x2 = -1.#INF00, x3 = 1.#SNAN0
y1 = 1.#INF00, y2 = -1.#INF00, y3 = 1.#QNAN0

Детальный вывод выглядит немного странно, но я думаю, что суть ясна.

PS .: Кажется, преобразование указателя не нужно. Просто используйте%f рассказатьprintf функция для интерпретацииunsigned long long переменная вdouble формат.

ДОБАВИТЬ 2

Из любопытства я проверил представление битов переменных с помощью следующего кода.

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, int len)
{
    int i;
    for (i = len-1; i>=0; i--)
    {
        printf("%.2x", start[i]);
    }
    printf("\n");
}

И я попробовал код ниже:

//check the infinity and NaN
unsigned long long x1 = 0x7ff0000000000000ULL; // +infinity as double
unsigned long long x2 = 0xfff0000000000000ULL; // -infinity as double
unsigned long long x3 = 0x7ff0000000000001ULL; // NaN as double
double y1 =* ((double *)(&x1));
double y2 =* ((double *)(&x2));
double y3 = *((double *)(&x3));

unsigned long long x4 = x1 + x2;  // I want to check (+infinity)+(-infinity)
double y4 = y1 + y2; // I want to check (+infinity)+(-infinity)

printf("\nx1: ");
show_bytes((byte_pointer)&x1, sizeof(x1));
printf("\nx2: ");
show_bytes((byte_pointer)&x2, sizeof(x2));
printf("\nx3: ");
show_bytes((byte_pointer)&x3, sizeof(x3));
printf("\nx4: ");
show_bytes((byte_pointer)&x4, sizeof(x4));

printf("\ny1: ");
show_bytes((byte_pointer)&y1, sizeof(y1));
printf("\ny2: ");
show_bytes((byte_pointer)&y2, sizeof(y2));
printf("\ny3: ");
show_bytes((byte_pointer)&y3, sizeof(y3));
printf("\ny4: ");
show_bytes((byte_pointer)&y4, sizeof(y4));

Выход:

x1: 7ff0000000000000

x2: fff0000000000000

x3: 7ff0000000000001

x4: 7fe0000000000000

y1: 7ff0000000000000

y2: fff0000000000000

y3: 7ff8000000000001

y4: fff8000000000000  // <== Different with x4

Странная часть: хотя x1 и x2 имеют битовую комбинацию, идентичную y1 и y2, сумма x4 отличается от y4.

А также

printf("\ny4=%f", y4);

дает это:

y4=-1.#IND00  // What does it mean???

Почему они разные? И как получается у4?

Ответы на вопрос(4)

Ваш ответ на вопрос