简体   繁体   English

在 c# 中将 ushort 转换为字节的最快方法是什么?

[英]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.我想将 ushort 转换为字节,如果 ushort 等于 ushort.MaxValue,则字节等于 0xFF,如果 ushort 等于 0,则字节等于 0x00。 Intuitively, this means getting rid of every other bit in the ushort bit array.直观地说,这意味着删除 ushort 位数组中的所有其他位。 What's the most efficient way of doing this in c#?在 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.您应该只右移 8(或除以 256)——在这种情况下,MaxValue 将是 0xFF 而 0 也将是 0x00。

Your way, 0x0001 would be 0x01, but 0x0002 would be 0x00, which is odd.按照您的方式,0x0001 将是 0x01,但 0x0002 将是 0x00,这很奇怪。

 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:编辑#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);请注意,上面使用了一些底边舍入,因此ushort.MaxValue - 1将变成字节 254。使用 Math.Round() 可能会更好,也许: return (byte)Math.Round(value * ratio);


Edit #2:编辑#2:

You originally stated:你原来说:

Intuitively, this means getting rid of every other bit in the ushort bit array.直观地说,这意味着删除 ushort 位数组中的所有其他位。

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.我将除以 256 并将该值设置为一个字节。 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.如果只有 0 == 0 和 65535 = 256,那么您可能不想四舍五入。 Am I missing something?我错过了什么吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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