Convert byte array to short array in C#
Asked Answered
K

7

16

I'm currently reading a file and wanted to be able to convert the array of bytes obtained from the file into a short array.

How would I go about doing this?

Kulak answered 9/7, 2009 at 15:23 Comment(1)
Do you want to convert 1 byte to 1 short, or 2 bytes to 1 short?Inexistent
K
15

One possibility is using Enumerable.Select:

byte[] bytes;
var shorts = bytes.Select(b => (short)b).ToArray();

Another is to use Array.ConvertAll:

byte[] bytes;
var shorts = Array.ConvertAll(bytes, b => (short)b);
Kendrakendrah answered 9/7, 2009 at 15:25 Comment(4)
Your original suggestion (before you added the second one later on) is rather inefficientUnbent
Another option would be bytes.Cast<short>().ToArray();Hobo
Actually, this results in a InvalidCastException. The short explanation is that this code implicitly causes an boxed byte to be unboxed to a short which is not a valid unboxing operation. For details, see #445971.Kendrakendrah
When I used var shorts[] = Array.ConvertAll(bytes, b => (short)b); I got each byte converted to a short not each pair of bytes converted.Messroom
T
68

Use Buffer.BlockCopy.

Create the short array at half the size of the byte array, and copy the byte data in:

short[] sdata = new short[(int)Math.Ceiling(data.Length / 2)];
Buffer.BlockCopy(data, 0, sdata, 0, data.Length);

It is the fastest method by far.

Tibia answered 30/10, 2010 at 18:27 Comment(2)
The solution i don't deserve, but the one i need right now!Dissimulate
Thanks! Great answer but I had to change the code slightly to: short[] sdata = new short[(int)Math.Ceiling(data.Length / 2.0)];. Otherwise, I would have gotten the following error: "The call is ambiguous between the following methods or properties: 'Math.Ceiling(decimal)' and 'Math.Ceiling(double)' "Selry
K
15

One possibility is using Enumerable.Select:

byte[] bytes;
var shorts = bytes.Select(b => (short)b).ToArray();

Another is to use Array.ConvertAll:

byte[] bytes;
var shorts = Array.ConvertAll(bytes, b => (short)b);
Kendrakendrah answered 9/7, 2009 at 15:25 Comment(4)
Your original suggestion (before you added the second one later on) is rather inefficientUnbent
Another option would be bytes.Cast<short>().ToArray();Hobo
Actually, this results in a InvalidCastException. The short explanation is that this code implicitly causes an boxed byte to be unboxed to a short which is not a valid unboxing operation. For details, see #445971.Kendrakendrah
When I used var shorts[] = Array.ConvertAll(bytes, b => (short)b); I got each byte converted to a short not each pair of bytes converted.Messroom
B
6

A shorthard is a compound of two bytes. If you are writing all the shorts to the file as true shorts then those conversions are wrong. You must use two bytes to get the true short value, using something like:

short s = (short)(bytes[0] | (bytes[1] << 8))
Bentlee answered 9/8, 2009 at 0:31 Comment(2)
This doesn't work. You have to do it like this to make it work: short s = (short)((bytes[0] << 8) | bytes[1]);Overripe
Assuming little endian, this should be: short s = (short)(bytes[0] | (bytes[1] << 8))Apothegm
G
2
short value = BitConverter.ToInt16(bytes, index);
Gurney answered 30/4, 2010 at 12:52 Comment(2)
This one uses index as LSB and index+1 as MSB. Is there one that follows BigEndian to use index as the MSB?Prosperus
Did you even read the question? It is about byte[] to short[] not short.Vigen
M
1

I dont know, but I would have expected another aproach to this question. When converting a sequence of bytes into a sequence of shorts, i would have it done like @Peter did

short s = (short)(bytes[0] | (bytes[1] << 8))

or

short s = (short)((bytes[0] << 8) | bytes[1])

depending on endianess of the bytes in the file.

But the OP didnt mention his usage of the shorts or the definition of the shorts in the file. In his case it would make no sense to convert the byte array to a short array, because it would take twice as much memory, and i doubt if a byte would be needed to be converted to a short when used elsewhere.

Melonymelos answered 15/11, 2016 at 9:59 Comment(0)
U
0
 short[] wordArray = Array.ConvertAll(byteArray, (b) => (short)b);
Unbent answered 9/7, 2009 at 15:26 Comment(1)
In my opinion, this would convert every byte into a short, which might not be the expected result als two bytes would represent a short ;-)Spoil
H
-2
byte[] bytes;
var shorts = bytes.Select(n => System.Convert.ToInt16(n)).ToArray();
Heterogynous answered 9/7, 2009 at 15:28 Comment(3)
That's extremely inefficient: Calling convert.ToInt16() for every element, storing it in a temporary list, and then copying it to an new array.Unbent
yes, it is inefficient. I'm thinking that it's safer, tho, then casting.Aldaaldan
Safer than casting? A cast of byte to short always works. It can never throw an exceptionUnbent

© 2022 - 2024 — McMap. All rights reserved.