Каков результат деления на ноль? - PullRequest
12 голосов
/ 07 ноября 2011

Для ясности, я не ищу NaN или бесконечность или спрашиваю, каким должен быть ответ на x/0.То, что я ищу, это:

На основе того, как выполняется аппаратное деление (я не знаю, как это делается), если деление должно быть выполнено с делителем 0, а процессор простоЧто же из этого выйдет с удовольствием в ходе операции?

Я понимаю, что это сильно зависит от дивидендов, поэтому для конкретного ответа я спрашиваю: что выплюнул бы компьютер, если бы он следовал своим стандартамоперация деления на 42 / 0?

Обновление:

Я постараюсь быть немного яснее.Я спрашиваю о реальных операциях, выполняемых с числами на уровне битов, чтобы достичь решения.Результат операции - просто биты.NaN и ошибки / исключения вступают в игру, когда делитель оказывается равным нулю.Если бы на самом деле произошло разделение, какие биты вышли бы?

Ответы [ 8 ]

12 голосов
/ 07 ноября 2011

Это может просто не остановить . Целочисленное деление может быть выполнено в линейное время посредством повторного вычитания: для 7/2 вы можете вычесть 2 из 7 в общей сложности 3 раза, так что это частное, а остаток (модуль) равен 1. Если вы должны были предоставить деление 0 на алгоритм, подобный этому, если бы не было механизма для его предотвращения, алгоритм не остановился бы: вы можете вычитать 0 из 42 бесконечное число раз, не доходя никуда.

С точки зрения типа это должно быть интуитивно понятно. Результатом неопределенного вычисления или не останавливающего вычисления является ⊥ («низ»), неопределенное значение, присущее каждому типу. Деление на ноль не определяется для целых чисел, поэтому оно должно по праву генерировать ⊥, вызывая ошибку или не завершаясь. Первое, вероятно, предпочтительнее. ;)

Другие, более эффективные (логарифмические) алгоритмы деления основаны на рядах, сходящихся к частному; для дивиденда 0, насколько я могу судить, они либо не сойдутся (т.е. не прекратят работу), либо приведут к 0. См. Division в Википедии.

Для деления с плавающей точкой аналогичным образом требуется особый случай: делить два числа с плавающей запятой, вычитать их показатели и целочисленные делить их значения. Тот же основной алгоритм, та же проблема. Вот почему в IEEE-754 есть представления для положительной и отрицательной бесконечности, а также ноль со знаком и NaN (для 0/0).

8 голосов
/ 07 ноября 2011

Для процессоров, которые имеют внутреннюю инструкцию «деления», например x86 с div, ЦП фактически вызывает программное прерывание, если кто-то пытается разделить на ноль.Это программное прерывание обычно перехватывается языковой средой выполнения и переводится в соответствующее исключение «деление на ноль».

5 голосов
/ 07 ноября 2011

Аппаратные делители обычно используют конвейерную структуру long .

Предположим, что мы говорим о целочисленном делении (в отличие от плавающей запятой); Первым шагом в длинном делении является выравнивание наиболее значимых (прежде чем пытаться вычесть делитель из дивиденда). Понятно, что это не определено в случае 0, так что кто знает, что будет делать аппаратное обеспечение. Если мы предположим, что это делает что-то вменяемое, следующим шагом будет выполнение log (n) вычитаний (где n - количество битовых позиций). Для каждого вычитания, которое приводит к положительному результату, в выходном слове устанавливается 1. Таким образом, результатом этого шага будет слово «все 1».

Деление с плавающей запятой требует трех шагов:

  • Принимая разницу показателей
  • Фиксированное разделение мантисс
  • Обработка особых случаев

0 представлен всеми 0 (как мантисса, так и показатель степени). Однако в мантиссе всегда подразумевается ведущий 1, поэтому, если бы мы не рассматривали это представление как особый случай, оно бы выглядело и действовало как чрезвычайно малая степень 2.

2 голосов
/ 07 ноября 2011

Это зависит от реализации. Стандарт IEE 754 с плавающей точкой [1] определяет значения бесконечности со знаком, поэтому в теории это должно быть результатом деления на ноль. Аппаратное обеспечение просто устанавливает флаг, если демонинатор равен нулю при операции деления. В этом нет магии.

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

[1] http://en.wikipedia.org/wiki/IEEE_754-2008

1 голос

На x86 происходит прерывание 0 и выходные регистры не изменяются

Пример минимального 16-битного реального режима (например, для добавления в загрузчик):

    movw $handler, 0x00
    movw %cs, 0x02
    mov $0, %ax
    div %ax
    /* After iret, we come here. */
    hlt
handler:
    /* After div, we come here. *
    iret

Как подробно запустить этот код || 32-битная версия .

В документации Intel для инструкции DIV не говорится, что обычные выходные регистры (ax == результат, dx == модуль) изменены, поэтому я думаю, что это означает, что они остаются неизменными.

Linux тогда обработает это прерывание, чтобы отправить SIGFPE процессу, который это сделал, то есть уничтожит его, если не обработать.

1 голос
/ 07 ноября 2011

Это фактически выплюнуло бы исключение.Математически 42/0 не определено, поэтому компьютеры не будут выдавать конкретное значение на эти входы.Я знаю, что деление может быть выполнено в аппаратном обеспечении, но хорошо спроектированное оборудование будет иметь своего рода флаг или прерывание, чтобы сообщить вам, что любое значение, содержащееся в регистрах, которые должны содержать результат, недопустимо.Многие компьютеры делают из этого исключения.

1 голос
/ 07 ноября 2011

Это был бы бесконечный цикл. Как правило, деление выполняется путем непрерывного вычитания, так же как умножение выполняется путем непрерывного сложения.

Итак, ноль - это специальный регистр, так как мы все равно знаем, каков ответ.

0 голосов
/ 31 декабря 2013

X / 0 Где X - элемент действительных чисел, который больше или равен 1, поэтому ответ X / 0 = бесконечность.

Метод деления (c #)

Int Counter = 0; /* used to keep track of the division */
Int X = 42;      /* number */
Int Y = 0;       /* divisor */
While (x > 0) { 
    X = X - Y; 
    Counter++;
}
Int answer = Counter;
...