Почему для вычитания байтов в C # требуется приведение типов?

Мне нужно выполнить следующий код в VS2008 .net 3.5 с помощью WinForms:

byte percent = 70;
byte zero = 0;

Bitmap copy = (Bitmap)image1.Clone();
...

Color oColor = copy.GetPixel(x, y);
byte oR = (byte)(oColor.R - percent < zero ? zero : oColor.R - percent);

Когда я оставляю «(byte)» в последней строке кода, я получаю сообщение об ошибке компилятора: «Невозможно неявно преобразовать тип 'int' в 'byte'». Если все относится к типу byte, а byte является целочисленным типом ... тогда зачем мне использовать приведение?


person Billy    schedule 29.05.2009    source источник
comment
Эрик Липперт говорит: «Я не считаю байты числами; Я думаю о них как о паттернах битов, которые можно интерпретировать как числа, символы, цвета или что-то еще. Если вы собираетесь выполнять с ними математические вычисления и рассматривать их как числа, то имеет смысл переместить результат в тип данных, который обычно интерпретируется как число. См. stackoverflow.com/questions/941584/byte-byte-int-why-c .   -  person Brian    schedule 03.06.2009
comment
Вы, ребята, понимаете, что отметили это как дубликат, хотя его спросили раньше, а здесь уже есть ссылка для ответа?   -  person Charlie Martin    schedule 27.11.2013
comment
Черт, теперь даже сказано, что он задавал раньше, хотя другой вопрос был задан тремя годами позже.   -  person Charlie Martin    schedule 18.09.2015
comment
На самом деле каждое значение данных - это битовая комбинация, которую можно интерпретировать как число.   -  person Charlie Martin    schedule 18.09.2015


Ответы (9)


Потому что вычитание приводит к целому числу. Насколько я помню, byte - это беззнаковый тип в C #, поэтому вычитание может вывести вас из области байтов.

person Charlie Martin    schedule 29.05.2009
comment
Вычитание может вывести вас из области применения любого числового типа. Это на самом деле не объясняет, почему нет оператора вычитания, зависящего от байта. - person John Gietzen; 18.09.2015
comment
Что ж, тогда ответ в том, что разработчики C # решили, что они им не нужны. - person Charlie Martin; 18.09.2015

Это потому, что результат вычитания байта не помещается в байт:

byte - byte = (0..255) - (0..255) = -255..255
person schnaader    schedule 29.05.2009
comment
Какое красивое графическое объяснение !!! - person Jhonny D. Cano -Leftware-; 29.05.2009
comment
Также нет целочисленных типов, кроме чисел с плавающей запятой или десятичных знаков. int также имеет конечный диапазон, поэтому (min_int - max_int) не подходит, но возвращает int. - person Adam Frisby; 29.05.2009
comment
@Adam: 1) числа с плавающей запятой и десятичные дроби не являются целочисленными типами. 2) Результаты вычитания для них также могут не подходить, так как они также имеют конечный (хотя и большой) диапазон. - person Brian; 03.06.2009

Арифметика по байтам по умолчанию дает значение типа int .

person Timothy Carter    schedule 29.05.2009
comment
Ссылка мертва ... - person Chiel ten Brinke; 10.10.2017
comment
@Timothy Cartner, На SO не рекомендуются ответы только по ссылке, по той причине, что он стоит уже год, с битой ссылкой. Не могли бы вы представить контекст? - person Rafael Herscovici; 07.08.2018

Поскольку арифметика по байтам по умолчанию возвращает целые числа, из двух возможных назначений более узкий тип нуля (байт) повышается до int (тип oColor.r - процент). Таким образом, тип операции - int. Компилятор без приведения не позволит вам назначить более широкий тип более узкому типу, потому что это операция с потерями. Следовательно, вы получите ошибку, если вы явно не скажете «Я знаю, что теряю некоторые данные, все в порядке» с приведением.

person Adam Wright    schedule 29.05.2009

Это потому, что вычитание byte возвращает int. Фактически, любые двоичные арифметические операции с bytes вернут int, поэтому требуется приведение.

person Andrew Hare    schedule 29.05.2009
comment
Я думаю, что на самом деле это вычитание ... - person Charlie Martin; 29.05.2009
comment
Упс - спасибо Чарли, я поправил. - person Andrew Hare; 29.05.2009
comment
Есть ли причина для голосования против? - person Andrew Hare; 29.05.2009
comment
По крайней мере, не я. Я думаю, у нас есть случайный отрицательный голос, у меня тоже есть один. - person Charlie Martin; 29.05.2009

Поскольку арифметические операции с sbyte, byte, ushort и short автоматически преобразуются в int. Наиболее вероятная причина этого заключается в том, что такие операции могут быть переполнены или недостаточны.

Таким образом, в вашей тернарной операции последний oColor.R - процент фактически дает int, а не байт. Таким образом, тип возвращаемого значения операции - int.

person PeterAllenWebb    schedule 29.05.2009

Поскольку арифметическое выражение в правой части оператора присваивания по умолчанию оценивается как int. В вашем примере percent по умолчанию int. Подробнее об этом можно прочитать на странице MSDN.

person Alexander Kahoun    schedule 29.05.2009

Попробуйте запустить этот код C #: object o = (byte) (1); о = (int) o; Что вы ожидаете? А теперь попробуй :)

Думаю, это правильно:

Эрик Липперт говорит: «Я не думаю о байтах как о« числах »; я думаю о них как о паттернах битов, которые можно интерпретировать как числа, символы, цвета или что-то еще. их и рассматривая их как числа, тогда имеет смысл переместить результат в тип данных, который обычно интерпретируется как число ".

Возможно, byte ближе к char, чем к int.

person Community    schedule 04.07.2009
comment
Вы можете использовать ту же логику для short, int и long. Они также представляют собой последовательности битов, которые можно интерпретировать как числа. - person David Klempfner; 21.05.2018
comment
Попробуйте рассказать это кому-нибудь, кто помнит 8-битные вычисления. За исключением sbyte, нет 8-битной структуры, более интерпретируемой как число, чем как байт. - person Paul Childs; 23.02.2021

FWIW, java также преобразует байты в int.

person Licky Lindsay    schedule 02.06.2009