按位运算,将3个字节组合为long

时间:2011-12-04 12:30:23

标签: vb.net bit-manipulation bit-shift

我正在尝试将三个字节值组合成一个Long值,如System.Drawing.Color.ToArgb()那样。

我查找了参考源代码以找到它并将其转换为VB .NET:

Return CLng((CInt(red) << 16 Or CInt(green) << 8 Or blue Or CInt(alpha) << 24) And -1)

它当然可以正常工作,但我真的不明白为什么alpha移位24是最后一个,而不是第一个(因此它将以良好的顺序24,16,8)。我真的不太了解按位操作。此外,这个代码片段适用于4个字节,这对我来说是多余的,我只需要三个字节,我想知道当字节只有三个时是否还需要Long,在这种情况下,Integer不会很好吗?

所以,我的问题是,如何重写此代码才能使用3个参数?我需要使用Long吗?并且,我知道这很愚蠢,但是有可能按168,0而不是16,8,0,24进行字节移位吗?这真的只是美学,但我是完美主义者。

提前致谢!

亚伦

3 个答案:

答案 0 :(得分:1)

我不熟悉VB.NET,但总的来说,移位计数没有正确或错误的顺序。它可以是24,16,8,0或16,24,0,8或任何其他顺序。

重新定义变量类型:有8位,16位和32位变量。这意味着您必须定义一个32位类型(长),以便为您的三个字节留出空间。 为便于访问,请将8个MSB位保留为0,以便将其用作24位值(0x00YYYYYY)。

答案 1 :(得分:1)

以下是一些不同的方法。 OR的顺序无关紧要。我添加了一些调试,以便您可以随时查看结果。

Private Sub Button1_Click(sender As System.Object, _
                          e As System.EventArgs) Handles Button1.Click

    Dim bar As Integer '32 bits

    'three byte values
    Dim x As Byte = 66
    Dim y As Byte = 65
    Dim z As Byte = 82

    'desired byte order
    '0xyz

    'one byte at a time
    bar = 0
    bar = bar Or (CInt(x) << 16)
    Debug.WriteLine(Convert.ToString(bar, 2).PadLeft(32, "0"c))
    bar = bar Or (CInt(y) << 8)
    Debug.WriteLine(Convert.ToString(bar, 2).PadLeft(32, "0"c))
    bar = bar Or (CInt(z) << 0) 'bar Or CInt(z)
    Debug.WriteLine(Convert.ToString(bar, 2).PadLeft(32, "0"c))

    'or as single statement
    bar = 0 Or (CInt(x) << 16) Or (CInt(y) << 8) Or CInt(z)
    Debug.WriteLine(Convert.ToString(bar, 2).PadLeft(32, "0"c))

    'in any order
    bar = 0 Or CInt(z) Or (CInt(y) << 8) Or (CInt(x) << 16)
    Debug.WriteLine(Convert.ToString(bar, 2).PadLeft(32, "0"c))

    'check results
    Dim foo() As Byte = BitConverter.GetBytes(bar) 'get the individual bytes
    Array.Reverse(foo) 'reverse
    Debug.WriteLine(System.Text.ASCIIEncoding.ASCII.GetChars(foo, 1, 3))
End Sub

答案 2 :(得分:1)

无关紧要,OR b与b OR a的值相同。 OR运算符是可交换的,就像+和*运算符一样。

Integer可以很好地存储该值,它有32位。使用UInteger可以用于处理大于127的alpha值,使值为负。当您尝试读取alpha值时,这会让您有点头疼。符号扩展产生一个较大的值,通过AND与255固定。长在VB6代码中很常见,因为它的Integer类型只有16位,而不是vb.net中的问题。