Страницы

Поиск по вопросам

понедельник, 25 ноября 2019 г.

Почему при сложении byte не переполняется?


Есть вот такой очень простой код.

using System;

class Test
{       
    static void Main()
    {
        byte x = byte.Parse(Console.ReadLine());
        byte y = byte.Parse(Console.ReadLine());
        Console.WriteLine(x + y);
    }
}


При вводе 123 и 221 выводит 344. Но ведь должно было произойти переполнение, почему оно не произошло? Почему не вывело 344 - 255 = 89?
    


Ответы

Ответ 1



Отличный вопрос! Согласно спецификации языка, определены следующие операторы числового сложения: int operator +(int x, int y); uint operator +(uint x, uint y); long operator +(long x, long y); ulong operator +(ulong x, ulong y); float operator +(float x, float y); double operator +(double x, double y); decimal operator +(decimal x, decimal y); Сложение байтов не определено. Таким образом, язык применяет конверсию, и превращает byte в int, чтобы использовать int operator +(int x, int y);. Почему выбирается именно перегрузка с int, а не, скажем, с uint? Обратимся снов к спецификации. Правила конверсии описаны здесь (перевод мой): Расширение типов для бинарных операторов состоит в применении следующих прави в том порядке, в каком они специфицированы тут: Если хотя бы один из операндов имеет тип decimal, другой операнд преобразуетс в тип decimal, или возникает ошибка времени привязки типов, если тип другого операнда — float или double. Иначе, если тип хотя бы одного из операндов double, другой операнд преобразуется в double. Иначе, если тип хотя бы одного из операндов float, другой операнд преобразуется в float. Иначе, если тип хотя бы одного из операндов ulong, другой операнд преобразуетс в ulong, или возникает ошибка времени привязки типов если другой операнд имеет тип sbyte, short, int или long. Иначе, если тип хотя бы одного из операндов long, другой операнд преобразуется в long. Иначе, если тип хотя бы одного из операндов uint и тип другого операнда sbyte short или int, оба операнда преобразуются в long. Иначе, если тип хотя бы одного из операндов uint, другой операнд преобразуется в uint. Иначе оба операнда преобразуются в int. В нашем случае работает последний пункт, остальные неприменимы. Значения преобразуются в int до сложения, и тип результата — int.

Ответ 2



Дело в том, что результат сложения byte + byte вовсе не обязан иметь тип byte. На самом деле, результат сложения имеет тип int, в который можно запросто поместить число 334. А проверить это утверждение можно вот так: using System; class Test { static void Main() { byte x = 123; byte y = 221; byte z = x + y; Console.WriteLine(z); } } Приведет к ошибке: Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)

Комментариев нет:

Отправить комментарий