Почему этот метод возвращает double.PositiveInfinity не DivideByZeroException?

Я запустил следующий фрагмент в VS2015 c# interactive и получил очень странное поведение.

> double divide(double a, double b)
. {
.     try
.     {
.         return a / b;
.     }
.     catch (DivideByZeroException exception)
.     {
.         throw new ArgumentException("Argument b must be non zero.", exception);
.     }
. }    
> divide(3,0)
Infinity    
> 3 / 0
(1,1): error CS0020: Division by constant zero
> var b = 0;
> 3 / b
Attempted to divide by zero.
> 

почему метод вернул бесконечность, в то время как 3 / 0 бросил ошибку, а 3 / b бросил формированную ошибку? Я могу заставить отдел накидали ошибка вместо возврата бесконечность?

Если я переформатирую метод в

double divide(double a, double b)
{
    if ( b == 0 )
    {
        throw new ArgumentException("Argument b must be non zero.", new DivideByZeroException());
    }
    return a / b;
}

будет ли новое исключение DivideByZeroException содержать ту же информацию и структуру, что и пойманное исключение будет?

4 ответов


это потому, что вы используете System.Double.

как заявил MSDN DivideByZeroException выбрасывается только для интегральных типов и Decimal.

это потому, что трудно определить "так называемый" ноль за двойную стоимость.

PositiveInfinity также является результатом деления на ноль с положительным дивиденды и отрицательные результаты от деления на ноль с a отрицательный дивиденд. (источник: в MSDN опять)

DivideByZeroException не подходит для типов с плавающей запятой. Примечание: Вы можете получить NaN хотя при попытке разделить на ноль с дивидендом нуля.


почему метод возвращает бесконечность, а 3 / 0 выдает ошибку и 3 / b бросил формализованную ошибку?

потому что в первом случае 0 не является целым числом, является двойной. А во втором-целое число. Здесь вы должны понять, что double-это число с плавающей запятой. Таким образом, он не имеет точного значения, такого как целое число. С другой стороны, целое число может быть представлено компьютером со 100% точностью.

здесь вы могли найдите очень хорошую статью о числах с плавающей запятой.


как уже говорилось выше, это связано с тем, что вы используете double в качестве делителя. Вы можете доказать это, используя пример переменных, но используя double вместо var.

> double a = 3;
> double b = 0;
> a/b
∞

Int в Java является дополнением 2. Целое число с двумя дополнениями не имеет битов, доступных для хранения специальных значений, таких как Infinity или NaN, поэтому, поскольку результат не представляется в желаемом типе, должно быть создано исключение. Числа с плавающей запятой не имеют этой проблемы (есть битовый шаблон, доступный для Бесконечности), и поэтому никаких исключений не требуется.