Преобразование 32-разрядного целого числа со знаком в 64-разрядное целое, сохраняя при этом точные биты - PullRequest
0 голосов
/ 25 марта 2019

У меня есть 32-битное значение, которое хранится в Integer типа 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

1 Ответ

1 голос
/ 25 марта 2019

Если бы у вас был метод для обращения битов байта, вы могли бы применить его четыре раза к байту целого числа.Небольшое исследование обнаружило, что 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-bit", потому что оннаписано для языка, где арифметическое переполнение игнорируется - методы, использующие 64-битные операции, полагаются на это, но это не значение по умолчанию для VB.NET.

...