locked
(byte | byte) is of type int32? RRS feed

  • Question

  • Hellos;

    I ran into an interesting tidbit while using logical operators for byte manipulation:
    byte a = 0xff, b = 0x0; 
    //byte c = a | b; //Exception 
    Console.Write((a | b).GetType().ToString()); //Int32 


    However, this works with longs just fine:
    Console.Write((0xffL | 0xffL).GetType().ToString()); //Int64 

    It seems to me that this is not the intended behavior - has anyone else had this problem?
    • Edited by cncarson Thursday, July 17, 2008 10:46 PM Checked for Longs
    Thursday, July 17, 2008 10:41 PM

Answers

  • Decided to look up why it is happening as it turns out binarycoder actually was in the right direction but got it wrong on the details. Although the X86 will perform will perform an 8 bit or without issues the 'ECMA-335 - Partition III: CIL Instruction Set' specification describes the or operator as :

    Bitwise OR of two integer values, returns an integer.

    since the or operator in MSIL only takes integers and bytes can be converted to ints without problems the results is going to be an integer as well hence you need to cast it back.

    This was fun :)

    http://www.ecma-international.org/publications/standards/Ecma-335.htm

    • Marked as answer by nobugz Sunday, July 20, 2008 4:33 PM
    Friday, July 18, 2008 7:27 PM

All replies

  • This is because of implicit binary numeric promotion, documented here:

    http://msdn.microsoft.com/en-us/library/aa691330.aspx

    This is not unique to .NET, but comes from a long history of this behavior in C, C++, and Java.

    Typically, there is no efficiency to be gained by having the CPU work on such narrow data values as byte.  So, they are implicitly promoted to int, a type which the processor can perform nearly all operations on with high efficiency.

    Consider that a 32-bit x86 CPU performs the OR instruction on two 32-bit registers and yields a 32-bit result into a third register.  There is no instruction to perform OR on just 8 bits.


    Thursday, July 17, 2008 11:07 PM
  • BinaryCoder said:

    Consider that a 32-bit x86 CPU performs the OR instruction on two 32-bit registers and yields a 32-bit result into a third register.  There is no instruction to perform OR on just 8 bits.




    Actually the result doesn't get stored in a 3rd register and it is allowed to use it on 8 bit registers like al,bl,cl etc...

    See page 499 of the Intel Architecture Software Developer's Manual, Volume 2 to see how it really works.

    http://developer.intel.com/design/pentiumii/manuals/243191.htm


     

    Friday, July 18, 2008 2:46 AM
  • This also applies to the Core architecture - page 12 of the
    http://download.intel.com/design/processor/manuals/253667.pdf

    I'm not arguing whether it takes less time to execute on an 8-bit vs a 64-bit value - it just seems awkward to me that a bitwise operation on a byte cannot be reassigned to a byte without a cast.


    Friday, July 18, 2008 4:17 PM
  • Decided to look up why it is happening as it turns out binarycoder actually was in the right direction but got it wrong on the details. Although the X86 will perform will perform an 8 bit or without issues the 'ECMA-335 - Partition III: CIL Instruction Set' specification describes the or operator as :

    Bitwise OR of two integer values, returns an integer.

    since the or operator in MSIL only takes integers and bytes can be converted to ints without problems the results is going to be an integer as well hence you need to cast it back.

    This was fun :)

    http://www.ecma-international.org/publications/standards/Ecma-335.htm

    • Marked as answer by nobugz Sunday, July 20, 2008 4:33 PM
    Friday, July 18, 2008 7:27 PM