Деление на ноль: неопределенное поведение или реализация, определенная в C и / или C ++? - PullRequest
20 голосов
/ 09 июня 2010

Относительно деления на ноль, стандарты говорят:

C99 6.5.5p5 - Результатом оператора / является частное от деления первого операнда на второй;результат оператора% - остаток.В обеих операциях, если значение второго операнда равно нулю, поведение не определено.

C ++ 03 5.6.4 - Бинарный / оператор возвращает частное, а бинарный оператор% возвращает остаток отделение первого выражения на второе.Если второй операнд / или% равен нулю, поведение не определено.

Если бы мы взяли вышеприведенные абзацы за чистую монету, ответ будет явно Неопределенное поведение для обоихязыки.Однако если мы посмотрим дальше в стандарте C99, то увидим следующий абзац, который кажется противоречивым (1):

C99 7.12p4 - макрос INFINITY расширяется до константного выражения типа float, представляющегоположительная или беззнаковая бесконечность, если имеется;

Есть ли в стандартах какое-то золотое правило , где Неопределенное поведение не может быть заменено (потенциально) противоречивым утверждением?За исключением этого, я не думаю, что было бы неразумно делать вывод, что если ваша реализация определяет макрос INFINITY, деление на ноль определено таковым.Однако, если ваша реализация не определяет такой макрос, поведение не определено.

Мне интересно, какой консенсус (если таковой имеется) по этому вопросу для каждого из двух языков,Изменится ли ответ, если мы говорим о целочисленном делении int i = 1 / 0 по сравнению с делением с плавающей запятой float i = 1.0 / 0.0?

Примечание (1) Стандарт C ++ 03 говорит о <cmath>библиотека, которая включает макрос INFINITY.

Ответы [ 8 ]

23 голосов
/ 09 июня 2010

Я не вижу противоречий. Деление на ноль не определено, точка. Там нет упоминания "... если не определена бесконечность" где-либо в цитируемом тексте.

Обратите внимание, что нигде в математике не определено, что 1/0 = бесконечность . Один может интерпретировать это таким образом, но это скорее личная, «быстрая» интерпретация стиля, а не звуковой факт.

12 голосов
/ 09 июня 2010

1/0 не бесконечность, только

lim 1/x = ∞ (x -> +0)
4 голосов
/ 20 июля 2016

Это был не математический вопрос, а вопрос C / C ++.

  • Согласно стандарту IEEE 754, который используют все современные компиляторы C / FPU, мы имеем
    • 3,0 / 0,0 = INF
    • 0,0 / 0,0 = NaN
    • -3,0 / 0,0 = -INF

FPU будет иметьфлаг состояния, который можно установить для создания исключения, если это необходимо, но это не является нормой.

INF может быть весьма полезным, чтобы избежать разветвления, когда INF является полезным результатом.Смотрите обсуждение здесь

http://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF

4 голосов
/ 09 июня 2010

С чего бы это?

Это не имеет смысла математически, это не так, как если бы 1 / x определялось как ∞ в математике в целом.Кроме того, вам, по крайней мере, понадобятся еще два случая: -1 / x и 0 / x также не могут равняться ∞.

См. деление наноль в целом и раздел о компьютерной арифметике в частности.

1 голос
/ 20 июля 2016

Реализации, которые определяют __STDC_IEC_559__, должны соблюдать требования, приведенные в Приложении F, что, в свою очередь, требует семантики с плавающей запятой, соответствующей МЭК 60559. Стандарт не устанавливает требований к поведению деления с плавающей запятой на ноль на реализации, которые не определяют __STDC_IEC_559__, но предназначены для тех, которые его определяют. В тех случаях, когда МЭК 60559 определяет поведение, но стандарт С не делает этого, компилятор, который определяет __STDC_IEC_559__, требует от стандарта С вести себя так, как описано в стандарте МЭК.

Как определено в МЭК 60559 (или стандарте США IEEE-754). Деление нуля на ноль дает NaN, деление числа с плавающей запятой на положительный ноль или буквальную константу ноль дает значение INF с тем же знаком, что и дивиденд. и деление числа с плавающей точкой на отрицательный ноль дает INF с противоположным знаком.

1 голос
/ 09 июня 2010

Для макроса INFINITY: существует явное кодирование для представления +/- бесконечности в стандарте IEEE754, то есть если все биты экспоненты установлены и все биты дроби очищены (если бит дроби установлен, он представляет NaN)

С моим компилятором, (int) INFINITY == -2147483648, поэтому выражение, которое оценивается как int i = 1/0, определенно даст неправильные результаты, если INFINITIY был возвращен

1 голос
/ 09 июня 2010

У меня только черновик C99. В разделе 7.12 / 4 говорится:

Макрос

    INFINITY

расширяется до постоянного выражения тип float, представляющий положительный или беззнаковая бесконечность, если имеется; еще к положительной константе типа float это переполняется во время перевода.

Обратите внимание, что INFINITY может быть определено в терминах переполнения с плавающей точкой, не обязательно деления на ноль.

0 голосов
/ 26 сентября 2014

Суть в том, что C99 (согласно вашим цитатам) ничего не говорит о INFINITY в контексте «определенной реализацией».Во-вторых, то, что вы процитировали, не показывает непоследовательного значения «неопределенного поведения».


[Цитирование страницы неопределенного поведения Википедии] «В C и C ++ также используется поведение, определяемое реализацией, где стандарт языкане определяет поведение, , но реализация должна выбрать поведение и должна документировать и соблюдать выбранные правила. "

Точнее, стандарт означает" определенный реализацией "(Iдумать только), когда он использует эти слова в отношении заявления, сделанного, поскольку «определенный реализацией» является специфическим атрибутом стандарта.Цитата C99 7.12p4 не упоминает «определяемый реализацией».

[Из C99 std (поздняя версия)] «неопределенное поведение: поведение при использовании непереносимой или ошибочной программной конструкции или ошибочных данных, для которого настоящий международный стандарт не предъявляет никаких требований "

Обратите внимание, что для неопределенного поведения не накладывается" никаких требований "!

[C99 ..]" определяемое реализацией поведение: неопределенное поведение, где каждая реализациядокументирует, как сделан выбор "

[C99 ..]" неопределенное поведение: использование неопределенного значения или другое поведение, когда этот международный стандарт предоставляет две или более возможностей и не предъявляет никаких дополнительных требований к тому, который выбран вany instance "

Документация является требованием для поведения, определенного реализацией.

...