Деление на 0 в C#.

Как мы знаем, делить на 0 нельзя. Но все же что будет происходить если все же поделим в языке программирования C#?

Если мы захотим разделить на ноль с использованием констант, нам сразу компилятор выдаст ошибку.

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

Например данный код,

private static void Main(string[] args)
 {
     int result = 999999 / 3;
     Console.Write(result);
     Console.Read();
}

Будет преобразован в соответствующий IL код:

Поэтому в таких простых ситуациях, этого нам не позволят сделать.

Если же деление на ноль произойдет в ходе выполнения программы, то будет выброшено соответствующее исключение «DivideByZeroException». Которое можно по необходимости обработать, как любое исключение.

Но не всегда можно обойтись только лишь обработкой этого исключения. Например:

private static void Main(string[] args)
{
    int x = 2;
    int y = -2;
    var result = 5 * 10.0d / (x + y);
    Console.Write(result);
    Console.Read();
}

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

Исключение DivideByZeroException возникает только при работе с целочисленными значениями и decimal. Поэтому нужно быть осторожным, при работе с числами с плавающей запятой, т.к. они позволяют делить на ноль, и при этом получаем  собственное для них значение «бесконечности». И если мы работаем с типами float и double с целочисленными выражениями, нужно быть готовым, что у нас будет приведение к данным типам и в результате может получиться бесконечность.

Кстати, при приведении, что значения double.PositiveInfinity (+бесконечности), что double.NegativeInfinity (-бесконечности) к типу int мы получим минимальное значение int, т.е. -2147483648. C NaN ситуация аналогична.

Это не является багом или какой-либо недоработкой, а наоборот это выполнено в соответствии со стандартами (IEEE) работы с типами с плавающей запятой.

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

Так же следует отметить, что при делении ноля на ноль, мы получим double.NaN.

Но если мы получили в результате бесконечности, это не означает что было обязательно деление на ноль, а это так же может означать, что было превышено double.MaxValue или double.MinValue. Поэтому только на результат вычисления мы не можем опираться, для определения деления на ноль.

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

Например, имеется метод с какими-то вычислениями, где могут быть операции с делением на ноль.

 private static void Main(string[] args)
 {
     try
     {
         double calc = Calc(50d, 0, 10, 2);
         Console.WriteLine(calc); // выведется бесконечность
     }
     catch (DivideByZeroException)
     {
         Console.WriteLine("DivideByZeroException 1");
     }

     try
     {
         double calc = Calc(50d, 10d, 10, 0);
         Console.WriteLine(calc);
     }
     catch (DivideByZeroException)
     {
         Console.WriteLine("DivideByZeroException 2"); // выведется сообщение об исключении
     }
     Console.Read();
 }

 private static double Calc(double a, double b, int c, int d)
 {
     double val1 = a / b;
     int val2 = c / d;
     return val1 / val2;
 }

Чтобы мы могли обработать случаи, когда будет деление на ноль, можно изменить метод Calc таким образом:

private static double Calc(double a, double b, int c, int d)
{
    if (b == 0)
        throw new DivideByZeroException();
    double val1 = a / b;
    int val2 = c / d;
    return val1 / val2;
}

Тогда у нас дважды будет обработано исключение деления на ноль.

Надеюсь статья была полезной. Делите на ноль аккуратно.

About the Author: Павел Бахвалов

1 комментарий

  1. Спасибо за статью!
    Было довольно интересно почитать и узнать что на ноль делить все же можно 🤯

Добавить комментарий

Войти с помощью: 

Ваш адрес email не будет опубликован. Обязательные поля помечены *