0

我有一个整数值,当满足某些条件时,必须像以下示例一样修改它:

00000001 10000000 11111111 00000000

变成

11111111 00000000 00000001 10000000

第一个 16 位字必须成为第二个字,反之亦然。我知道我可以轻松地将我的 long 转换为 0 和 1 的数组,然后我可以使用 2 的幂来重建我需要的 long,但我想知道是否还有其他更好、更快的方法来做它。更快是指执行明智。如果它更复杂但有更好的结果,我仍然可以。

谢谢

4

2 回答 2

3

您可以使用移位和按位或:

value = (value << 16) | (value >> 16)
于 2012-11-20T14:59:43.217 回答
0

在下面的代码中,我测试了 Pubby 答案的 VB.NET 版本SwapMath,针对显式结构偏移替代方案SwapBits. 前者快了大约 40 倍,可能部分原因是它几乎肯定是内联的。

Option Infer On
Option Strict On
Option Explicit On

Imports System.Runtime.InteropServices
Imports System.Diagnostics

Namespace Stackoverflow
Module SO13475894
  <StructLayout(LayoutKind.Explicit)> _
  Structure UShorts
    <FieldOffset(0)> Public x As UInteger
    <FieldOffset(0)> Public xLow  As UShort
    <FieldOffset(2)> Public xHigh As UShort
  End Structure

  Function SwapMath(ByVal x As UInteger) As UInteger
    Return (x >> 16) Or (x << 16)
  End Function

  ' About 40 times slower :-(
  Function SwapBits(ByVal x As UInteger) As UInteger
    Dim swapper As UShorts
    swapper.x = x
    Dim swapTemp = swapper.xLow
    swapper.xLow = swapper.xHigh
    swapper.xHigh = swapTemp
    Return swapper.x
  End Function

Sub Main()

  Dim x As UInteger = Convert.ToUInt32("11111111000000000000000110000000", fromBase:=2)

  Dim y = SwapMath(x)
  Dim z = SwapMath(y)
  Console.WriteLine(x)
  Console.WriteLine(Convert.ToString(y, toBase:=2))
  Console.WriteLine(z=x)

  y = SwapBits(x)
  z = SwapBits(y)
  Console.WriteLine(Convert.ToString(y, toBase:=2))
  Console.WriteLine(z=x)

  Const N As Integer = 100000000
  Dim sw = Stopwatch.StartNew

  For i = 1 To N
    y = SwapMath(x)
    z = SwapMath(y)
  Next
  sw.Stop
  Console.WriteLine(sw.Elapsed.TotalMilliseconds/CDbl(N))

  sw = Stopwatch.StartNew

  For i = 1 To N
    y = SwapBits(x)
    z = SwapBits(y)
  Next
  sw.Stop
  Console.WriteLine(sw.Elapsed.TotalMilliseconds/CDbl(N))

End Sub
End Module
End Namespace
于 2012-11-22T10:01:19.197 回答