我有一个 32 位值,存储在 VB.Net 类型整数(即 Int32(中。 我只对位感兴趣 - 而不是数值。 有时第 32 位是一个被解释为负数的位。 我的目标是反转实际位。 我的原始数据被编码为从右到左(LSB最右(的位,并以从左到右(MSB最左边(读回。我正在改编别人的代码和设计。我的一个想法可能是暂时转换为长,但我不知道该怎么做并正确保留第 32 位。
Public Shared Function ReverseBits32(ByVal n As Integer) As Integer
Dim result As Integer = 0
For i As Integer = 0 To 32 - 1
result = result * 2 + n Mod 2
n = n >> 1 'n Or 2
Next
Return result
End Function
如果你有一个反转字节位的方法,你可以把它应用于整数的字节四次。一些研究发现 Bit Twiddling Hacks。
Module Module1
Sub ShowBits(a As Integer)
Dim aa = BitConverter.GetBytes(a)
Console.WriteLine(String.Join(" ", aa.Select(Function(b) Convert.ToString(b, 2).PadLeft(8, "0"c))))
End Sub
Function ReverseBits(b As Byte) As Byte
' From https://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
Dim c = CULng(b)
Return CByte((((c * &H802UL And &H22110UL) Or (c * &H8020UL And &H88440UL)) * &H10101UL >> 16) And &HFFUL)
End Function
Function ReverseBits(a As Integer) As Integer
Dim bb = BitConverter.GetBytes(a)
Dim cc(3) As Byte
For i = 0 To 3
cc(3 - i) = ReverseBits(bb(i))
Next
Return BitConverter.ToInt32(cc, 0)
End Function
Sub Main()
Dim y = -762334566
ShowBits(y)
y = ReverseBits(y)
ShowBits(y)
Console.ReadLine()
End Sub
End Module
测试值的输出:
10011010 10110010 10001111 11010010
01001011 11110001 01001101 01011001
我使用了"no 64 位"方法,因为它是为忽略算术溢出的语言编写的 - 使用 64 位运算的方法依赖于它,但它不是 VB.NET 的默认值。