16

I have to following code in VS2008 .net 3.5 using 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);

When I leave the "(byte)" off the last line of code, I get a compiler error saying it "Cannot implicitly convert type 'int' to 'byte'." If everything is of type byte and byte is an integer type... then why do I need to have the cast?

Michael Myers
  • 178,094
  • 41
  • 278
  • 290
Billy
  • 2,432
  • 5
  • 30
  • 36
  • 6
    Eric Lippert says, "I don't think of bytes as "numbers"; I think of them as patterns of bits that could be _interpreted_ as numbers, or characters, or colors or whatever. If you're going to be doing math on them and treating them as numbers, then it makes sense to move the result into a data type that is more commonly interpreted as a number." See http://stackoverflow.com/questions/941584/byte-byte-int-why-c . – Brian Jun 03 '09 at 13:26
  • 5
    You guys do realize you've marked this as a duplicate even though it was asked *before* the "already has an answer here" link? – Charlie Martin Nov 26 '13 at 22:13
  • Hell, now it even says "asked before" even though the other question was asked three years later. – Charlie Martin Sep 18 '15 at 19:52
  • 1
    Uh, actually, *every* data value is a bit pattern that can be interpreted as a number. – Charlie Martin Sep 18 '15 at 19:54

9 Answers9

16

Because subtraction is coercing up to an integer. As I recall, byte is an unsigned type in C#, so subtraction can take you out of the domain of bytes.

Charlie Martin
  • 103,438
  • 22
  • 180
  • 253
11

That's because the result of a byte subtraction doesn't fit in a byte:

byte - byte = (0..255) - (0..255) = -255..255
schnaader
  • 46,785
  • 9
  • 98
  • 132
8

Arithmetic on bytes results in an int value by default.

Timothy Carter
  • 14,238
  • 7
  • 40
  • 62
4

Because arithmetic on bytes returns integers by default so of the two possible assignments the narrower type of zero (byte) is promoted to int (that of oColor.r - percent). Thus the type of the operation is an int. The compiler will not, without a cast, allow you to assign a wider type to a narrower type, because it's a lossy operation. Hence you get the error, unless you explicitly say "I know I'm losing some data, it's fine" with the cast.

Adam Wright
  • 47,483
  • 11
  • 126
  • 149
2

This is because byte subtraction returns an int. Actually any binary arithmetic operations on bytes will return an int, so the cast is required.

Andrew Hare
  • 320,708
  • 66
  • 621
  • 623
2

Because arithmetic operations on sbyte, byte, ushort, and short are automatically converted to int. The most plausible reason for this is that such operations are likely to overflow or underflow.

Thus, in your ternary operation, the final oColor.R - percent, actually results in an int, not a byte. So the return type of the operation is int.

PeterAllenWebb
  • 9,596
  • 3
  • 34
  • 44
1

Try to run this C# code: object o = (byte)(1); o = (int)o; What do you expect? Now try :)

I think this is right:

Eric Lippert says, "I don't think of bytes as "numbers"; I think of them as patterns of bits that could be interpreted as numbers, or characters, or colors or whatever. If you're going to be doing math on them and treating them as numbers, then it makes sense to move the result into a data type that is more commonly interpreted as a number."

Perhaps byte is closer to char than to int.

  • 1
    You could use the same logic for short, int and long. They are also strings of bits which could be interpreted as numbers. – David Klempfner May 21 '18 at 11:41
  • Try telling that to someone who remembers 8 bit computing. Excepting sbyte, there is no 8 bit structure more commonly interpreted as a number than byte. – Paul Childs Feb 23 '21 at 00:46
1

Because the arithmetic expression on the right-hand side of the assignment operator evaluates to int by default. In your example percent defaults to int. You can read more about it on the MSDN page.

Alexander Kahoun
  • 2,406
  • 22
  • 36
0

FWIW, java also promotes bytes to int.

Licky Lindsay
  • 1,038
  • 6
  • 10