c# - 移位同时保留模式

标签 c# bit-manipulation

如果之前有人问过/回答过这个问题,我深表歉意,但说实话,我什至不确定如何正确地表达这个问题。我有以下位模式:

0110110110110110110110110110110110110110110110110110110110110110

我正在尝试进行一次转变,以保留我的基本模式;我的第一直觉是使用右旋转 ((x >> count) | (x << (-count & 63)))但我的位模式的不对称导致:

0011011011011011011011011011011011011011011011011011011011011011 <---错误

问题是最高有效位(最左边)最终是 0,而不是所需的 1:

1011011011011011011011011011011011011011011011011011011011011011 <---右

我正在寻找的这个函数有一个通俗的名称吗?如果没有,我该如何实现这个想法?

其他信息:

  • 虽然这个问题与语言无关,但我目前正在尝试使用 C# 来解决这个问题。
  • 我使用的位模式是完全可预测的,并且始终具有相同的结构;该模式以一个零开头,后跟 n - 1个(其中 n 是奇数),然后无限重复。
  • 我想在没有条件操作的情况下完成此任务,因为它们首先就违背了使用按位操作的目的,但也许我别无选择......

最佳答案

您的数字结构如下:

B16  B15  B14  B13  B12  B11  B10  B09  B08  B07  B06  B05  B04  B03  B02  B01  B00

  ?    0    1    1    0    1    1    0    1    1    0    1    1    0    1    1    0

?需要在移位后出现在 MSB(B15 或 B63 或其他)中。它从何而来?好吧,找到了最接近的副本 n右边的地方:

B13    0    1    1    0    1    1    0    1    1    0    1    1    0    1    1    0
 ^--------------/

如果你的单词有宽度 w ,这是1 << (w-n)

                 *

所以你可以这样做:

var selector = 1 << (w-n);
var rotated = (val >> 1) | ((val & selector) << (n-1));

但您可能需要多类制。然后我们需要构建一个更宽的掩模:

  ?    0    1    1    0    1    1    0    1    1    0    1    1    0    1    1    0
            *    *    *    *    *

在这里我选择假装n = 6 ,它只需要是基本 n 的倍数即可,并且大于shift 。现在:

var selector = ((1UL << shift) - 1) << (w - n);
var rotated = (val >> shift) | ((val & selector) << (n - shift));

使用您的模式进行工作演示:http://rextester.com/UWYSW47054

很容易看出输出的周期为 3,符合要求:

  1:B6DB6DB6DB6DB6DB
  2:DB6DB6DB6DB6DB6D
  3:6DB6DB6DB6DB6DB6
  4:B6DB6DB6DB6DB6DB
  5:DB6DB6DB6DB6DB6D
  6:6DB6DB6DB6DB6DB6
  7:B6DB6DB6DB6DB6DB
  8:DB6DB6DB6DB6DB6D
  9:6DB6DB6DB6DB6DB6
 10:B6DB6DB6DB6DB6DB
 11:DB6DB6DB6DB6DB6D

关于c# - 移位同时保留模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45599188/

相关文章:

sql-server - T-SQL 中的位翻转操作

c# - 更新后图像未保存,在 c# 中使用 FileStream 或简单位图

c# - C# 中是否有一个类来处理几个 INT(范围为 2 INT-1-10)

c# - 如何获得名称未知的 DbEntityEntry EntityKey 对象

c# - 在 EventArgs<T> 形式的 .NET 框架中是否有现成的东西?

python - 在 Python 中反转数字的(二进制)数字的巧妙方法?

c# - 我怎样才能把函数放在其他cs文件中?

c# - 在 C# 中使用 ExpressionVisitor 识别 lambda 表达式中的括号

c - 如何使用按位运算将 4 个 uint8_t 转换为单个 float

c - 如何在C中一次清除多个位?