Посмотрите на этот код. Как думаете какой будет результат?
Double a = 1;
Double b = 3;
Double c = a/b;
Double d = c * 3;
Single a3 = 1;
Single b3 = 3;
Single c3 = a3 / b3;
Single d3 = c3 * 3;
decimal a2 = 1;
decimal b2 = 3;
decimal c2 = a2 / b2;
decimal d2 = c2 * 3;
Console.WriteLine("Double:");
Console.WriteLine(c.ToString());
Console.WriteLine(d.ToString());
Console.WriteLine();
Console.WriteLine("Single:");
Console.WriteLine(c3);
Console.WriteLine(d3);
Console.WriteLine();
Console.WriteLine("Decimal:");
Console.WriteLine(c2);
Console.WriteLine(d2);
Не смотря на то, что, казалось бы, все три результата должны быть идентичны, только при использовании типа decimal результат такой же как и при обычном делении/умножении на бумажке. И double и single в результате дадут единицу. Почем так получается, спросите вы? Все из-за того, что single и double содержат два дополнительных разряда в конце, благодаря которым можно получить исходное значение при выполнении арифметических действий в обратном порядке. Увидеть их можно вот так:
Console.WriteLine("{0:R}", c);
На этом, кстати, интересности относительно single и double не заканчиваются как думаете что будет в результате выполнения вот этого кода?
Double number = 123;
Double zero = 0;
Double result = number / zero;
На самом деле исключения "деление на ноль" не будет. В результате выполнения этого кода result будет равно Double.PositiveInfinity. А если -123 разделить на ноль, то Double.NegativeInfinity.
А теперь перейдем к наиболее часто используемому численному типу - Integer. Посмотрите на вот этот код:
int num1 = 10;
int num2 = 20;
int num3 = num1 / num2;
decimal num3_1 = num1 / num2;
Вы уже догадались, что в обоих случаях результат будет равен нулю? А все потому, что при целочисленном делении результат округляется вниз к ближайшему целому. Ну и еще один пример, совсем не очевидный. Как думаете что будет в результате?
int max = int.MaxValue;
int res = max + 1;
На самом деле не будет ошибки переполнения. Будет int.MinValue. Все потому, что по умолчанию в C# переполнение int не проверяется и добавление единицы к максимальному значению просто превращает его в минимальное. Если же вы хотите чтобы в случае переполнения получалась ошибка нужно либо включить проверку переполнения в компиляторе, либо сделать вот так:
checked
{
int max = int.MaxValue;
int res = max + 1;
}
Комментариев нет:
Отправить комментарий