Divide By Zero не создает исключение DivideByZeroException с плавающей запятой или с двойным... почему?

Я играл с некоторыми Math и заметил, что вместо бросания DivideByZeroException плавающие и двойные числа получают значение Infinitity при делении на ноль. Почему это так?

    [TestMethod]
    public void TestFloatDivideByZero()
    {

        double myDouble = 100.0;
        var DbzDouble = 1000.0 / ((myDouble - myDouble) / myDouble);
        // Infinity

        float myFloat = 100.0f;
        var DbzFloat = 1000.0 / ((myFloat - myFloat) / myFloat);
        // Infinity

        decimal myDecimal = 100M;
        var DbzDecimal = 1000M / ((myDecimal - myDecimal) / myDecimal);
        // DivideByZeroException

        int myInt = 100;
        var DbzInt = 1000 / ((myInt - myInt) / myInt);
        // DivideByZeroException

    }

1 ответ

Решение

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

Преобладающий вывод заключался в том, что с этим нельзя справиться и что единственный разумный вариант - отключить исключения. Большинство любой современной библиотеки поддержки времени выполнения следует этому правилу.

CLR не является исключением, он конфигурирует FPU, чтобы не генерировать исключения, и позволяет процессору генерировать бесконечность. Также закреплено в стандарте CLI, а также в стандарте языка C#. При необходимости вам нужно использовать Double.IsInfinity(), чтобы создать собственное исключение.

Другие вопросы по тегам