Каков результат деления на ноль?

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

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

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

Обновление:

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


person yoozer8    schedule 06.11.2011    source источник
comment
Не по теме: принадлежит math.stackexchange.com   -  person Alastair Pitts    schedule 07.11.2011
comment
NaN выйдет. Вы что, думали, что компьютеры скрывают от нас настоящий результат?   -  person ceejayoz    schedule 07.11.2011
comment
@AlastairPitts Ты уверен? Поскольку речь идет о том, как процессор справится с операцией, он кажется более подходящим для этого, чем чисто математический сайт.   -  person yoozer8    schedule 07.11.2011
comment
Инструкции чипа — это жестко закодированные логические элементы, сделанные из сырых материалов, вытравленных в кремнии, фактическая компоновка которых, вероятно, уникальна для каждой архитектуры. Я думаю, что мы все спекулируем здесь. Нам нужно знать внутреннюю схему ИС для конкретного процессора - и что произойдет, если часть этой схемы будет удалена, чтобы точно ответить на этот вопрос. Но да, они жестко закодировали проверку на 0-делитель. Что может вас куда-то вывести, так это изучение того, как новые компьютерные архитектуры реализуют свою логику разделения.   -  person Merlyn Morgan-Graham    schedule 07.11.2011
comment
Голосование ОТ. Из часто задаваемых вопросов - вы должны задавать только практические вопросы, на которые можно ответить, основанные на реальных проблемах, с которыми вы сталкиваетесь.   -  person Merlyn Morgan-Graham    schedule 07.11.2011
comment
@Jim: Моя ошибка, я неправильно понял суть вопроса. Все еще не уверен, что это по теме для SO (даже несмотря на то, что на него был успешно дан ответ)   -  person Alastair Pitts    schedule 07.11.2011


Ответы (8)


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

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

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

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

person Jon Purdy    schedule 06.11.2011
comment
Это можно осуществить повторным вычитанием, но на практике это не так... - person Oliver Charlesworth; 07.11.2011
comment
@OliCharlesworth: Верно. Я редактировал, чтобы добавить примечание о других алгоритмах. - person Jon Purdy; 07.11.2011
comment
Даже при длинном делении аппаратное обеспечение завершит работу. Он будет выполнять фиксированное количество этапов. - person Oliver Charlesworth; 07.11.2011

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

person Greg Hewgill    schedule 06.11.2011
comment
Это не отвечает на заданный вопрос. - person Jon Purdy; 07.11.2011
comment
Да, вопрос был отредактирован с момента моего ответа. Я поставил +1 вашему. - person Greg Hewgill; 07.11.2011

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

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

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

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

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

person Oliver Charlesworth    schedule 07.11.2011
comment
Я не удивлюсь, если найдутся машины, в которых инструкция деления на ноль остановит исполнительный блок до тех пор, пока контролирующая схема таймера не обнаружит ошибку. Добавление оборудования, чтобы избежать зависания попытки деления на ноль, сделало бы компьютер более дорогим, поэтому я не удивлюсь, если некоторые машины не будут беспокоиться. - person supercat; 11.02.2014

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

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

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

person Deleted    schedule 06.11.2011
comment
Нет, с математической точки зрения на 0 делить нельзя. НИКОГДА. Это просто не определено. То, что мы называем бесконечностью, — это символ, обозначающий произвольно большое число, являющееся результатом деления чего-то почти на 0 (но не на 0). - person Alvaro; 31.12.2013

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

Таким образом, ноль — это особый случай, поскольку мы все равно знаем, каков ответ.

person Will Hartung    schedule 06.11.2011
comment
Действительно? Умножение и деление - операции с линейным временем? - person Seth Carnegie; 07.11.2011

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

person aleph_null    schedule 07.11.2011
comment
Кроме того, я пишу этот комментарий, чтобы никто не сказал, что 42/0 на самом деле бесконечность. БОГОХУЛЬСТВО! 42/X стремится к бесконечности, когда X стремится к 0, но 42/0 просто не определено. Большая разница. - person aleph_null; 07.11.2011
comment
Совершенно верно, 42/x = oo — это просто символ для представления произвольно большого числа: результат растет по мере того, как x приближается к 0. - person Alvaro; 31.12.2013

В 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 процессу, который это сделал, что уничтожит его, если не будет обработано.

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 21.10.2015

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

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

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;
person Anonymous    schedule 31.12.2013
comment
Я спрашиваю о реальных операциях, выполняемых с числами на битовом уровне, чтобы найти решение. -ОП. - person Joel Peltonen; 31.12.2013