简体   繁体   中英

What's the fastest way to convert a ushort to a byte in c#?

I want to convert a ushort to a byte such that if the ushort equals ushort.MaxValue, then the byte equals 0xFF and if the ushort equals zero, then the byte equals 0x00. Intuitively, this means getting rid of every other bit in the ushort bit array. What's the most efficient way of doing this in c#?

Remember that the top bits are the "most significant" -- meaning that they should be the ones you want to preserve when scaling it down.

You should just right-shift 8 (or divide by 256) -- MaxValue would be 0xFF and 0 would be 0x00 in that case too.

Your way, 0x0001 would be 0x01, but 0x0002 would be 0x00, which is odd.

 byte output = 0;
 //ushort us = value;
 if (us == ushort.MaxValue)
 {
     output = 0xff;
 }
 else
 {     
    ushort ush = us & 0xAAAA; // 0xAAAA => Bin 1010101010101010
    int i = 7;
    while(ush > 0)
    {
       output = output | ((ush & 0x0001) << i);
       ush = ush  >> 2;                  
       i--;
    }
 }

Something like this?

// set this in a constructor or something.
// it is constant and does not need recalcualted each time.
private float ratio = 255 / 65535; // (or byte.MaxValue / ushort.MaxValue)

// do math
public byte Calcualte(ushort value)
{
    return (byte)value * ratio;
}

// test
Assert.AreEqual(byte.MinValue, Calcualte(ushort.MinValue));
Assert.AreEqual(byte.MaxValue, Calcualte(ushort.MaxValue));

Edit #1:

Note that the above is using some floor rounding, so ushort.MaxValue - 1 would turn into byte 254. It might be better to use Math.Round() instead, maybe: return (byte)Math.Round(value * ratio);


Edit #2:

You originally stated:

Intuitively, this means getting rid of every other bit in the ushort bit array.

I think this is a false statement, because if you ditch every other bit, then you get:

0000000000000000 => 00000000 (0 => 0 : correct)
0101010101010101 => 00000000 (21845 => 0 : incorrect)
1010101010101010 => 11111111 (43690 => 255 : incorrect)
1111111111111111 => 11111111 (65535 => 255 : correct)

I would divide by 256 and set that value to a byte. You can determine whether or not you want to round things off, but creating some overly complex bit masking methodology seems a bit harsh when you are just trying to scale down a value to a smaller set. If only 0 == 0 and 65535 = 256, then you may not want to round things off. Am I missing something?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM