Мы все знаем, 0/0
есть Undefined
и возвращает ошибку, если бы я поместил ее в калькулятор, и если бы я создал программу (по крайней мере, на C), ОС прервала бы ее, когда я попытался бы разделить на ноль.
Но что меня интересует, так это то, что компьютер даже пытается делить на ноль или он просто имеет «встроенную защиту», так что, когда он «видит», 0/0
он возвращает ошибку даже до попытки его вычисления?
math
error-handling
arithmetic
Ankush
источник
источник
Ответы:
Процессор имеет встроенное обнаружение. Большинство архитектур наборов команд указывают, что ЦП будет перехватывать обработчик исключений для целочисленного деления на ноль (я не думаю, что все равно, будет ли делиться ноль).
Вполне возможно, что проверка делителя нуля происходит параллельно в аппаратном обеспечении вместе с попыткой выполнить деление, однако обнаружение нарушающего условия фактически отменяет деление и прерывает ловушку, поэтому мы не можем действительно сказать, является ли какая-то часть из этого попытался разделение или нет.
(Аппаратное обеспечение часто работает таким образом, выполняя несколько операций параллельно, а затем выбирая соответствующий результат, потому что тогда каждая из операций может быть начата сразу же, вместо того, чтобы сериализовать выбор соответствующей операции.)
Тот же механизм прерывания и исключения будет также использоваться при включении обнаружения переполнения, которое вы обычно запрашиваете, используя различные инструкции add / sub / mul (или флаг этих инструкций).
Деление с плавающей запятой также имеет встроенное обнаружение деления на ноль, но возвращает другое значение ( IEEE 754 указывает NaN ) вместо перехвата в обработчик исключений.
Гипотетически говоря, если процессор пропустил какое-либо обнаружение для попытки деления на ноль, проблемы могут включать:
источник
Это зависит от языка, от компилятора, от того, используете ли вы целые числа или числа с плавающей запятой и так далее.
Для числа с плавающей запятой большинство реализаций используют стандарт IEEE 754 , где деление на 0 четко определено. 0/0 дает четко определенный результат NaN (не число), а x / 0 для x ≠ 0 дает либо + Infinity, либо -Infinity, в зависимости от знака x.
В таких языках, как C, C ++ и т. Д. Деление на ноль вызывает неопределенное поведение. Таким образом, согласно определению языка, все может произойти. Особенно то, чего ты не хочешь. Как и все отлично работает, когда вы пишете код и уничтожаете данные, когда его использует ваш клиент. Так что с языковой точки зрения не делайте этого . Некоторые языки гарантируют, что ваше приложение потерпит крах; это зависит от них, как это реализовано. Для этих языков деление на ноль приведет к сбою.
Многие процессоры имеют какую-то встроенную инструкцию «делить», которая будет вести себя по-разному в зависимости от процессора. На 32-битных и 64-битных процессорах Intel инструкции «делить» приводят к сбою приложения при попытке деления на ноль. Другие процессоры могут вести себя по-другому.
Если компилятор обнаружит, что при выполнении некоторого кода произойдет деление на ноль, и компилятор хорош для своих пользователей, он, скорее всего, выдаст вам предупреждение и сгенерирует встроенную инструкцию «делить», чтобы поведение такой же.
источник
EXCEPTION_INT_DIVIDE_BY_ZERO
значение вEXCEPTION_RECORD
котором будет обрабатываться (надеюсь) установлен изготовленном Exception Handling HandlerПохоже, вам интересно, что произойдет, если кто-то создаст процессор, который явно не проверяет ноль перед делением. Что произойдет, полностью зависит от осуществления деления. Не вдаваясь в подробности, один вид реализации даст результат, в котором установлены все биты, например 65535 на 16-битном процессоре. Другой может повесить трубку.
источник
Поскольку
x/0
бессмысленно, точка зрения, компьютеры всегда должны проверять деление на ноль. Здесь есть проблема: программисты хотят вычислять(a+b)/c
без необходимости проверять, имеет ли этот расчет смысл. Внутренний ответ на деление на ноль ЦП + тип числа + операционная система + язык заключается в том, чтобы либо сделать что-то довольно радикальное (например, аварийно завершить программу), либо сделать что-то слишком мягкое (например, создать значение, которое не смысл, такой как IEEE с плавающей точкойNaN
, число, которое "не число").В обычных условиях программист должен знать,
(a+b)/c
имеет ли смысл. В этом контексте нет причин проверять деление на ноль. Если происходит деление на ноль, и если машинный язык + язык реализации + тип данных + ответ операционной системы на это должен привести к аварийному завершению программы, это нормально. Если ответ заключается в создании значения, которое в конечном итоге может загрязнить каждое число в программе, это тоже нормально.Ни «что-то радикальное», ни «слишком мягкое» не является правильным решением в мире высоконадежных вычислений. Эти ответы по умолчанию могут убить пациента, разбить авиалайнер или взорвать бомбу не в том месте. В среде с высокой надежностью программист, который пишет,
(a+b)/c
будет забран до смерти во время проверки кода, или в наше время, возможно, будет забран автоматически до смерти инструментом, который проверяет верботные конструкции. В этой среде этот программист должен вместо этого написать что-то вродеdiv(add(a,b),c)
(и, возможно, некоторую проверку состояния ошибки). Под капотомdiv
(и такжеadd
) функции / макросы защищают от деления на ноль (или переполнения в случаеadd
). То, что влечет за собой эта защита, зависит от конкретной реализации.источник
Мы уже знаем это
x/0
и0/0
не имеем четко определенных ответов. Что произойдет, если вы попытаетесь0/0
все равно рассчитать ?В современной системе вычисление передается в MPU внутри CPU и помечается как недопустимая операция, возвращаясь
NaN
.В гораздо более старых системах, таких как домашние компьютеры 80-х годов, у которых не было деления на кристалле, расчеты выполнялись любым программным обеспечением. Есть несколько возможных вариантов:
0
1
log(0)
и программа либо использует свои процедуры обработки ошибок, либо вылетает0
и e 0 = 1, что дает результат1
Другими словами, то, что произойдет, будет зависеть от реализации, и можно будет написать программное обеспечение, которое будет давать правильные и предсказуемые результаты для каждого значения, но, казалось бы, странные значения для
0/0
этого, тем не менее, все еще внутренне согласованы.источник
NaN
.very inefficient
для деления. Стоимость арифметики (сложение = вычитание) <= умножение <= деление. Если у вас нет MPU, который может выполнять деление за то же количество тактов, что и сложение (обычно один), тогда деление обходится дороже, чем сложение и вычитание, и, как правило, дороже, чем умножение.