Почему целочисленное деление на ноль приводит к исключению с плавающей запятой?
Деление на ноль в программе на C приводит к аварийному завершению с сообщением об ошибке Floating point exception (core dumped)
, Это неудивительно для деления с плавающей запятой, но почему это говорится, когда происходит целочисленное деление на ноль? Использует ли целочисленное деление FPU под колпаком?
(Это все на Linux под x86, кстати.)
4 ответа
Использует ли целочисленное деление FPU под колпаком?
Нет, Linux просто генерирует SIGFPE и в этом случае (это устаревшее имя, использование которого теперь расширено). Действительно, Спецификация Single Unix определяет SIGFPE как "Ошибочная арифметическая операция".
Мое предположение об историческом объяснении этого могло бы состоять в том, что исходное оборудование Unix не создавало ловушку для целочисленного деления на ноль, поэтому название SIGFPE
имело смысл. (Программисты ассемблера PDP, подтвердите?) Затем позже, когда система была портирована (или, в случае Linux, переопределена) на оборудование с ловушкой с целочисленным делением на ноль, было нецелесообразно добавлять новый номер сигнала, поэтому старый приобрел новое значение и теперь имеет немного запутанное имя.
man signal
отмечает:
Целочисленное деление на ноль имеет неопределенный результат. На некоторых архитектурах он генерирует сигнал SIGFPE. (Также деление наиболее отрицательного целого числа на -1 может генерировать SIGFPE.)
Для этого может быть много разных причин реализации.
Например, модуль FPU на платформе x86 поддерживает форматы как с плавающей запятой, так и целочисленные для чтения аргументов и записи результатов. В те времена, когда сама платформа была 16-разрядной, некоторые компиляторы использовали FPU для выполнения деления с 32-разрядными целочисленными операндами (поскольку потери точности для 32-разрядных данных отсутствуют). При таких обстоятельствах не было бы ничего необычного в получении подлинной ошибки FPU для неверного 32-разрядного целочисленного деления.