1 / (1,0 / 0,0) оценивается как ноль в C - PullRequest
0 голосов
/ 04 мая 2018

При оценке приведенного ниже выражения в C, вывод равен нулю, а не бесконечности. Но в соответствии с правилом приоритета оператора C вывод должен быть бесконечным.

double a=1/(1.0/0.0);
printf("a : %.18le\n", a);

Пожалуйста, объясните, как это оценивает компилятор gcc?

Ответы [ 4 ]

0 голосов
/ 04 мая 2018

Давайте разберем выражение:

double a = 1 / (1.0 / 0.0);

сначала вычисляется выражение 1.0 / 0.0 и получается +infinity.

Затем вычисляется следующее выражение: 1.0 / +infinity, что приводит к 0.0, который является выходным значением, которое вы получаете.

int 1 повышен до double до оценки.

Все остальные ответы также применимы.

0 голосов
/ 04 мая 2018

Стандарт C не предписывает, как удваивается обработка чисел NaN и Inf, однако с gcc поведение диктуется IEEE 754 в строгом режиме: https://en.wikipedia.org/wiki/IEEE_754

из этой статьи:

Стандарт определяет пять исключений, каждое из которых возвращает значение по умолчанию значение и имеет соответствующий флаг статуса, который (за исключением определенных случаи недополнения) возникает при возникновении исключения. Нет другого обработка исключений требуется, но дополнительная не по умолчанию рекомендуются альтернативы (см. ниже).

Пять возможных исключений:

  • Недопустимая операция: математически не определена, например, квадратный корень из отрицательного числа. По умолчанию возвращает qNaN.

  • Деление на ноль: операция с конечными операндами дает точный бесконечный результат, например, 1/0 или log (0). По умолчанию возвращает ± бесконечность.

  • Переполнение: результат слишком велик для правильного представления (т. Е. Его показатель степени с неограниченным диапазоном показателей будет больше, чем Emax). Возвращает ± бесконечность по умолчанию для режима округления до ближайшего.
  • Underflow: результат очень мал (вне нормального диапазона) и неточен. Возвращает ненормальное или ноль по умолчанию.
  • Неточно: точный (то есть необоснованный) результат не может быть представлен точно. По умолчанию возвращает правильно округленный результат.

Однако на некоторых платформах модуль с плавающей точкой, совместимый с ieee 754, недоступен, и вам следует либо задействовать программную библиотеку с плавающей точкой, либо проконсультироваться с руководством по платформам о том, что происходит. Например, у arm в fpu есть режим RunFast, который запрещает строгое соблюдение.

Некоторая дополнительная информация: Какие-либо реальные процессоры не используют IEEE 754?

0 голосов
/ 04 мая 2018

Деление чего-либо, кроме бесконечности, на бесконечность приводит к нулю. GCC дает правильный результат.

0 голосов
/ 04 мая 2018

Операции с бесконечностью, как определено IEEE-754, в основном следуют тем же правилам, что и очень очень большие конечные числа. При делении 1 на n получается число, которое становится ближе к нулю при увеличении n, поэтому округленный предел равен нулю.

...