Яркий пример того, для чего в ядре каждого современного устройства, начиная от калькулятора до сверх мощных серверов и ПК, есть прерывания на случай абсурдных команд.



Деление на ноль — это абсурдный процесс, который Вы не можете и не должны выполнять. Простой, но все еще не совершенный ответ объясняет, что если Вы делите что-то на нуль, процесс приближается к бесконечности.

Что Вы получите при попытке разделить, например, число 20 на 0 используя современный ПК или телефон? Для тех кто не знает — ниже приведены скриншоты с примером.





На вопрос, почему мы получаем такой результат, существует простой ответ. В любой ОС присутствует инструкция, уберегающая от подобных проблем. Также и в самом ядре устройства есть внутренние прерывания, как раз на случай такого рода команд. Но думаю, многим будет интересно узнать, что случится, если убрать подобные прерывания?

Попробовав произвести деление на 0 на механическом калькуляторе, Вы увидите ужасную агонию в попытках решить абсурдную математическую задачу. Как показано на видео, где «сертифицированный» математик пытается разделиться на ноль на механическом калькуляторе, названном Facit ESA-01.



Несомненно — забавно, но это также небольшая иллюстрация того, как работают механические компьютеры. Машины используют серию зубчатых колес и шестеренок разных размеров, которые вращаются вместе в то время как дифференциальное отношение между механизмами помогает отслеживать фактическую математику. Это видео 1953 года очень подробно демонстрирует главный принцип механического калькулятора.



Когда механический калькулятор работает, он использует подобный механический процесс. Деление на любое число — это последовательное вычитание. Как пример, давайте разделим двадцать на четыре:

  1. 20 — 4 = 16
  2. 16 — 4 = 12
  3. 12 — 4 = 8
  4. 8 — 4 = 4
  5. 4 — 4 = 0


Пять шагов, чтобы добраться до нуля, так что ответ пять. Все просто!

Конечно, если Вы используете тот же процесс при делении на ноль, он становится цикличным, потому что последовательность для 20 при делении на ноль:

  1. 20 — 0 = 20
  2. 20 — 0 = 20
  3. 20 — 0 = 20
  4. 20 — 0 = 20
  5. 20 — 0 = 20


И так далее, до самого конца времен.

Без подробного рассмотрения «внутренностей» Facit ESA-01 трудно сказать, что происходит внутри него в данной ситуации. Но Вы можете быть уверены, что основной причиной для бесконечной обработки является попытка машины выполнить бесконечную последовательность команд одну за другой. И так по кругу.

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

Комментарии (26)


  1. MaximChistov
    30.03.2016 15:50
    +8

    по-моему прерывания — это всем другое…


  1. EndUser
    30.03.2016 16:23
    +3

    Всегда думал, что прерывания нужны для переключения задач.

    Деление на ноль не вызывает бесконечного цикла, результат операции определён как «не определённый», а прерывание к этому случаю впихнули просто потому, что результат пользователю всё равно уже не понадобится, а программисту надо исправлять софт (если конечно его стиль программирования не подразумевает catch по любой специфике предметной области).

    Наверное в математических пакетах может иметь смысл деления на ноль, и операция выдаёт вполне внятные результаты математически образованному пользователю без панических прерываний. Нет?


    1. oleg0xff
      30.03.2016 16:47

      октава пишет:
      `

      10 / 0
      warning: division by zero
      ans = Inf
      `


      1. EndUser
        30.03.2016 16:53

        10 / -0 = -inf, надеюсь.


        1. oleg0xff
          30.03.2016 17:01

          да. Проверил.


          1. toxicdream
            30.03.2016 17:36

            -10 / -0 = ?


            1. oleg0xff
              30.03.2016 20:34

              ans = Inf


    1. rereture
      30.03.2016 16:53
      -5

      Это какие же результаты?
      В мат.анализе 0 не севсем ноль, а бесконечно малое число, но всетаки число, поэтому и получается бесконечно большое число — бесконечность.
      А если делить именно на 0, то есть на ничто?


      1. choupa
        30.03.2016 20:28
        +6

        Сразу видно, что в матане вы сильны.


        1. rereture
          30.03.2016 22:50
          -7

          Ну так что будет же? Давай великий математик, подели на ноль, именно на ноль, а не на бесконечно малую, а то трындеть не мешки ворочать.


          1. Sychuan
            30.03.2016 23:51

            Вообще-то деление на 0 обычно не имеет смысла. В комплексном анализе, вводится бесконечно удаленная точка ?. Поэтому некоторые соотношения вроде z/0 = ? разрешены. В вещественном анализе, деление на 0 обычно не определено. Есть кое какие алгебраические структуры, где деление на 0 осуществляется, например wheel


            1. rereture
              31.03.2016 00:21
              -3

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


        1. nikolaynnov
          31.03.2016 01:33
          +2

          Да ладно вам, человек наверное впервые после окончания вуза вспомнил что-то из курса (скорее всего пределы), а вы его так сразу слили.


    1. compdemon
      30.03.2016 17:06

      «Сначала, в начальной школе, нам говорят, что нельзя вычитать из большего меньшее. Потом, в старших классах, оказывается, что всё-таки можно. Тогда говорят, что нельзя делить на ноль. Потом, в высшей школе, оказывается, что иногда всё-таки можно.»

      Прерывания еще и корректно обработать нужно.
      А то будет как в испытаниях мотороловских процессоров в автопилоте истребителей и полетах в районе Мертвого моря.


      1. kaichou
        30.03.2016 18:00
        +1

        > Тогда говорят, что нельзя делить на ноль. Потом, в высшей школе, оказывается, что иногда всё-таки можно.
        Нет, нельзя. Не создано такой непротиворечивой системы, где можно.
        Бесконечно-малые — всё-таки не ноль.


        1. Foolleren
          30.03.2016 18:42
          +1

          деление на ноль это неопределенность, от неё можно избавиться, ценой появления неопределённости в другом месте.


          1. EndUser
            30.03.2016 19:54
            -1

            «Сингулярность, это место, где мы, согласно теории Эйнштейна, делим на ноль. ?Н?е?л?ь?з?я? плохо делить на ноль.

            Теория струн — это ведь „теория всего“, общая теория поля. Она должна дать ответы на те вопросы, на которые не даёт ответов теория Эйнштейна. Она р?а?з?р?е?ш?и?т? ?д?е?л?и?т?ь? ?н?а? ?н?о?л?ь? легально».
            /Нил Деграсс Тайсон, интервью на PBS/
            ;-)


        1. Sychuan
          30.03.2016 23:52

          Вообще-то есть, но не слышал, чтобы они где-то активно применялись сегодня


      1. choupa
        30.03.2016 20:35

        Потом, в высшей школе, оказывается, что иногда всё-таки можно.

        Только, пожалуйста, не делайте это часто.


    1. Alexeyslav
      30.03.2016 17:28
      +1

      Как раз и не вызывает, потому что эта ситуация предусмотрена заранее. А прерывание предусмотрено не просто так, а для того чтобы в программу не вставлять проверку на «неопределённый результат» после каждой команды деления.
      Вместо этого, в случае попытки деления на ноль возникает прерывание, а обработчик этого прерывания в большинстве случаев прерывает выполнение расчёта и отправляет сообщение об ошибке выше. Это если обработчик назначен, иначе прерывание происходит на системном уровне и системе не остаётся ничего другого кроме как прибить процесс в котором возникло это прерывание.


      1. EndUser
        30.03.2016 18:47
        +2

        Значит так же логично поднимать прерывания на неуказанную дату рождения, на отсутствие денежного счёта, на неверный формат массы тела, на пустой остаток на складе, выход за предельно допустимую перегрузку манёвра, на многие другие ситуации, с которыми удобнее «не вставлять проверку после каждой команды»? ;-)


        1. WebConn
          30.03.2016 21:30

          Ага. Осталось только ввести в процессоре команды на определение неуказанной даты рождения ;)
          Для таких случаев давно изобретён try/catch, если что. Поведение аналогично, только читать и писать проще.


          1. EndUser
            31.03.2016 00:16
            +1

            Можно и на ноль делить в блоке try-catch.


            1. nikolaynnov
              31.03.2016 01:36

              Конечно можно. Только по стандарту C++ try/catch ловит только языковые исключения. Всё остальное это нестандартные платформо-специфичные приблуды. В той же винде для отлова SEH'ов надо __try блок использовать.


    1. DrGluck
      03.04.2016 17:31

      Если мне не изменяет склероз, в Windows Ошибка деления (Divide Error) относится к SEH, к которой, в том числе относятся всякие забавные штуки типа Breakpoint (Контрольная точка), Invalid Opcode (Недопустимый код операции), а также Page Fault (Ошибка обращения к странице), возникающая при каждом обращении к замаппированной, но ещё не прочитанной странице файла.


  1. Des77
    03.04.2016 17:20

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