8

How do I split a ushort into two byte variables in C#?

I tried the following (package.FrameID is ushort):

When I try to calculate this with paper&pencil I get the right result. Also, if FrameID is larger than a byte (so the second byte isn't zero), it works.

array[0] = (byte)(0x0000000011111111 & package.FrameID);
array[1] = (byte)(package.FrameID >> 8);

In my case package.FrameID is 56 and the result in array[0] is 16 instead of 56.

How can I fix this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user2071938
  • 2,055
  • 6
  • 28
  • 60

2 Answers2

20

Use BitConverter

var bytes = BitConverter.GetBytes(package.FrameID);
EZI
  • 15,209
  • 2
  • 27
  • 33
  • Thanks alot! But any Idea whats the problem with my solution? – user2071938 Sep 03 '13 at 08:42
  • 1
    @user2071938 `0x0000000011111111` is a 8-byte **hex** number. They are not bits as you think. it should be `0x00ff` – EZI Sep 03 '13 at 08:43
  • @user2071938 1 hex digit stands for 4 bits, so 1 byte will correspond to 2 hex digits. – King King Sep 03 '13 at 08:44
  • This is the best solution. Regarding the constant `0x0000000011111111`, it _seems_ to be an 8-byte number (16 hex digits), but since the leading 8 hex digits are all zero, it is interpreted as a 4-byte number. And since the first non-zero digit (`1`) is between `1` and `7`, not between `8` and `f`, this is an `int`, not a `uint`. You can try `var a = 0x11223344;` (`int`), `var b = 0x81223344;` (`uint`), `var c = 0x112233448899aabb;` (`long`), `var d = 0x812233448899aabb;` (`ulong`). – Jeppe Stig Nielsen Sep 03 '13 at 09:14
  • old question, but BitConverter is risky since it depends on the endianness of the system see answers here: https://stackoverflow.com/questions/8241060/how-to-get-little-endian-data-from-big-endian-in-c-sharp-using-bitconverter-toin – shelbypereira Sep 09 '20 at 13:36
12

0x0000000011111111 is not a binary number, it's a hex number. You need to use 0x0ff instead.

However, since the result is a byte and casting to a byte will discard the upper bits anyway, you don't actually need to and the result. You can just do this:

array[0] = (byte)package.FrameID;
array[1] = (byte)(package.FrameID >> 8);

(That's assuming that you are not using checked code. If you are, then casting a value greater than 255 to a byte will cause an exception. You will know if you are using checked code.)

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • `0x0f` is 1 byte, if we perform a `bit and` operation on it and the `ushort`, the return value is only the lower-nibble of the lower byte, I think it's `0x00ff`. – King King Sep 03 '13 at 08:48
  • You could also use `0x0000000011111111` if you wanted to use the binary number (notice leading 0b instead of 0x) – Lonefish Nov 21 '19 at 17:11