我正在尝试将三个字节值组合成一个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进行字节移位吗?这真的只是美学,但我是完美主义者。
提前致谢!
亚伦
答案 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中的问题。