views:

903

answers:

9

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?

+2  A: 

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
I think that's subtraction, actually....
Charlie Martin
Oops - thanks Charlie, I corrected it.
Andrew Hare
Is there a reason for the downvote?
Andrew Hare
Wasn't me, at least. I think we're having a random downvoter, I got one too.
Charlie Martin
+7  A: 

Arithmetic on bytes results in an int value by default.

Timothy Carter
+3  A: 

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
+9  A: 

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
+5  A: 

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

byte - byte = (0..255) - (0..255) = -255..255
schnaader
What a nice graphic explanation !!!
Jhonny D. Cano -Leftware-
Neither does any integer type except floats or decimals. int is of finite range too, so (min_int - max_int) wont fit, but it returns an int.
Adam Frisby
@Adam: 1) floats and decimals are not integer types. 2) Results of subtractions for these also may not fit, as these also have a finite (though large) range.
Brian
+1  A: 

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  A: 

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
A: 

FWIW, java also promotes bytes to int.

Licky Lindsay
+1  A: 

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.