我有一个整数值,当满足某些条件时,必须像以下示例一样修改它:
00000001 10000000 11111111 00000000
变成
11111111 00000000 00000001 10000000
第一个 16 位字必须成为第二个字,反之亦然。我知道我可以轻松地将我的 long 转换为 0 和 1 的数组,然后我可以使用 2 的幂来重建我需要的 long,但我想知道是否还有其他更好、更快的方法来做它。更快是指执行明智。如果它更复杂但有更好的结果,我仍然可以。
谢谢
我有一个整数值,当满足某些条件时,必须像以下示例一样修改它:
00000001 10000000 11111111 00000000
变成
11111111 00000000 00000001 10000000
第一个 16 位字必须成为第二个字,反之亦然。我知道我可以轻松地将我的 long 转换为 0 和 1 的数组,然后我可以使用 2 的幂来重建我需要的 long,但我想知道是否还有其他更好、更快的方法来做它。更快是指执行明智。如果它更复杂但有更好的结果,我仍然可以。
谢谢
您可以使用移位和按位或:
value = (value << 16) | (value >> 16)
在下面的代码中,我测试了 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