Посмотрите на этот код. Как думаете какой будет результат?
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; }
Комментариев нет:
Отправить комментарий