C# 如何清除最重要的位?

C# 如何清除最重要的位?,c#,bit-manipulation,C#,Bit Manipulation,如何将int中的最高有效位从1更改为0?例如,我想将01101改为0101。像这样进行位运算的最简单方法是使用左移位运算符(编辑:简化(并解释)答案 我在下面给出的答案是,如果您的唯一目标是将最重要的位设置为零,那就太过分了 代码的最后一位构造了一个位掩码,其中包含数字中的所有位 mask |= mask >> 1; mask |= mask >> 2; mask |= mask >> 4; mask |= mask >> 8; mask |= m

如何将int中的最高有效位从1更改为0?例如,我想将01101改为0101。

像这样进行位运算的最简单方法是使用左移位运算符(编辑:简化(并解释)答案

我在下面给出的答案是,如果您的唯一目标是将最重要的位设置为零,那就太过分了

代码的最后一位构造了一个位掩码,其中包含数字中的所有位

mask |= mask >> 1;
mask |= mask >> 2;
mask |= mask >> 4;
mask |= mask >> 8;
mask |= mask >> 16;
以下是它对给定32位无符号整数执行的一系列计算:

mask = originalValue
mask:               01000000000000000000000000000000
mask |= mask >> 1:  01100000000000000000000000000000
mask |= mask >> 2:  01111000000000000000000000000000
mask |= mask >> 4:  01111111100000000000000000000000
mask |= mask >> 8:  01111111111111111000000000000000
mask |= mask >> 16: 01111111111111111111111111111111
由于它会进行位右移(不环绕),因此它将永远不会将高于最高有效位的位设置为1。由于它使用的是逻辑
,因此您将永远不会将任何尚未为零的值显式设置为零

从逻辑上讲,这将始终创建一个位掩码,该掩码将填充整个
uint
,直到并包括最初设置的最高有效位,但不超过最高有效位

从该掩码可以相当容易地将其缩小,以包括除最初设置的最高有效位以外的所有位:

mask = mask >> 1: 00111111111111111111111111111111
然后只需对原始值执行逻辑
,它会将数字中的所有最高有效位设置为零,直到并包括原始值中的最高有效位:

originalValue &= mask: 00000000000000000000000000000000
我在这里使用的原始数字很好地显示了掩模构建过程,但它没有很好地显示上次的计算。让我们用一些更有趣的示例值(问题中的值)来完成计算:

以下是您正在寻找的价值:

originalValue &= mask: 00000000000000000000000000000101
既然我们可以看到这是可行的,让我们把最后的代码放在一起:

uint SetHighestBitToZero(uint originalValue)
{
    uint mask = originalValue;

    mask |= mask >> 1;
    mask |= mask >> 2;
    mask |= mask >> 4;
    mask |= mask >> 8;
    mask |= mask >> 16;

    mask = mask >> 1;

    return originalValue & mask;
}

// ...
Console.WriteLine(SetHighestBitToZero(13)); // 1101
五,

(即0101)

我给出的原始答案

对于这类问题,我经常引用这篇文章:

您需要的特定部分称为“查找整数的整数日志基2(也称为最高位集的位置)”

以下是一系列解决方案中的第一个(每个方案都比前一个方案更优):

本文中的最终解决方案是(转换为C#):

一旦找到最高设置位,只需将其屏蔽:

originalValue &= ~(uint)(1 << r); // Force bit "r" to be zero

originalValue&=~(uint)(1如果您将其作为整数,则代码结果将始终显示为零。可能是字符串操作将输出您想要的内容,但不确定这将如何帮助您。使用如下所示的字符串:

  string y = "01101";
  int pos = y.IndexOf("1");
  y = y.Insert(pos, "0");
  y = y.Remove(pos + 1, 1);
int x=0xD;//01101
int wk=x;
int-mask=1;

而(0!=(wk>>=1))面具的灵感来源于梅林·摩根·格雷厄姆的答案

static uint fxn(uint v)
{
    uint i = v;

    v |= v >> 1; 
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;

    return (v >> 1) & i;
}

您可以使用以下内容(未经测试):


“0上的第一个1”是什么意思?执行逻辑and运算,如01101&01101=01101我相信问题是:“逐位遍历整数。第一次遇到1时,将其更改为零。其他一切保持不变。”您的“位容器”是什么类型?int、long、string…?
(1@L.B.它们是二进制值我写评论时它们不是。这个答案不能解决OP要求的问题,因为
a=13
只是一个例子(OP说“例如”)。很明显,OP想要的是一个适用于任意整数的解决方案。这看起来很像《黑客之乐》@luketorjussen:谢谢你的插件!我去看看那本书:)有人检查过这个功能吗?@L.B:我没有,但据说那个网站有。如果你不喜欢答案中的那个,那个网站上还有3到4个变体。在谷歌搜索了几遍后,我找到了这个答案,看起来它链接到了描述算法的文章:@Merlyn Morgan Graham,我不想争论算法。我想说的是什么假设是,您的代码不符合问题中的要求。请检查您的代码,然后查看我的简化答案。问题清楚地标记为
位操作
,因此OP想要的是速度。虽然您的答案的结果是正确的,但通过将
int
转换为
字符串
destr来实现这是问题的初衷。
originalValue &= ~(uint)(1 << r); // Force bit "r" to be zero
  string y = "01101";
  int pos = y.IndexOf("1");
  y = y.Insert(pos, "0");
  y = y.Remove(pos + 1, 1);
int x = 0xD; //01101
int wk = x;
int mask = 1;
while(0!=(wk >>= 1)) mask <<= 1;
x ^= mask; //00101
static uint fxn(uint v)
{
    uint i = v;

    v |= v >> 1; 
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;

    return (v >> 1) & i;
}
int a = 13; //01101
int value = 0x80000000;
while ((a & value) != value)
{
  value = value >> 1;
}
if (value > 0)
  a = a ^ value;