【问题标题】:Convert 32-bit signed integer to 64-bit integer while preserving the exact bits将 32 位有符号整数转换为 64 位整数,同时保留精确位
【发布时间】:2019-08-15 20:27:51
【问题描述】:

我有一个 32 位值,它存储在 VB.Net 类型整数(即 Int32)中。我只对位感兴趣,而不是数值。有时第 32 位是一个被解释为负数的位。我的目标是反转实际位。我的原始数据被编码为从右到左(LSB 最右边)的位,并以从左到右(MSB 最左边)的方式读回。我正在改编别人的代码和设计。我的一个想法可能是暂时转换为 long 但我不知道如何做到这一点并正确保留第 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

【问题讨论】:

  • 如果您只对位感兴趣,为什么要使用有符号整数?
  • 我从一个示例应用程序开始,该应用程序最初使用 8 位值,但使用 32 位整数实现。这是有道理的,因为它将具有更高的性能。我的使用需要 32 位值。如果我此时尝试转换数据类型,将大大延迟我的项目。我将编辑问题以更准确地解释我的要求。
  • 它不允许我编辑。所以我需要一个函数来完全反转 32 位有符号整数中的位。当第 32 位为 1 时,我将其绊倒,因此将其设为负数。
  • 那么您真正需要的只是一种将 32 位整数中的位反转的方法,而这正是您遇到的问题?您根本不需要转到 64 位,只要有其他方法可以反转 32 位?
  • 是的,抱歉我没说清楚。

标签: vb.net types type-conversion


【解决方案1】:

如果你有一种方法可以反转一个字节的位,你可以将它应用到整数的字节四次。一点研究发现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

我使用“无 64 位”方法,因为它是为忽略算术溢出的语言编写的 - 使用 64 位操作的方法依赖于它,但它不是 VB.NET 的默认设置。

【讨论】:

  • 这需要我一些时间来解决,但我假设“CByte((((c * &H802UL And &H22110UL) Or (c * &H8020UL And &H88440UL)) * &H10101UL >> 16) And &HFFUL) “正在处理符号位?这看起来很有希望。
  • A Byte 未签名。 BitConverter.GetBytes 无需任何解释即可获取原始字节。所以符号位不会进入它:)
猜你喜欢
  • 2013-12-22
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多