如何清除最高有效位?

2023-11-25

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


编辑:简化(并解释)答案

我在下面给出的答案是多余的,如果你only目标是将最高有效位设置为零。

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

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。由于它使用的是逻辑or,您永远不会将任何尚未为零的值显式设置为零。

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

从该掩码中可以很容易地将其缩小以包含所有内容but最初设置的最高有效位:

mask = mask >> 1: 00111111111111111111111111111111

然后做一个逻辑and与原始值相反,它将把数字中的所有最高有效位设置为零,直到并包括原始值的最高有效位:

originalValue &= mask: 00000000000000000000000000000000

我在这里使用的原始数字很好地显示了掩模构建过程,但它并没有很好地显示最后的计算。让我们用一些更有趣的示例值(问题中的值)来进行计算:

originalValue: 1101
mask = originalValue
mask:               00000000000000000000000000001101
mask |= mask >> 1:  00000000000000000000000000001111
mask |= mask >> 2:  00000000000000000000000000001111
mask |= mask >> 4:  00000000000000000000000000001111
mask |= mask >> 8:  00000000000000000000000000001111
mask |= mask >> 16: 00000000000000000000000000001111
mask = mask >> 1:   00000000000000000000000000000111

这是您正在寻找的值:

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

5

(即0101)

我给出的原始答案

对于这类问题,我经常参考这篇文章:

“有点摆弄黑客”

您想要的特定部分称为“查找整数的以 2 为底的整数对数(也称为最高位集的位置)”。

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

http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious

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

uint originalValue = 13;
uint v = originalValue; // find the log base 2 of 32-bit v
int r;  // result goes here

uint[] MultiplyDeBruijnBitPosition = 
{
  0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
  8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};

v |= v >> 1; // first round down to one less than a power of 2 
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

r = (int)MultiplyDeBruijnBitPosition[(uint)(v * 0x07C4ACDDU) >> 27];

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

originalValue &= ~(uint)(1 << r); // Force bit "r" to be zero
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何清除最高有效位? 的相关文章

随机推荐

  • 在 Spring Data Rest 中修改 @OneToMany 实体而不使用其存储库

    在我的项目中我使用对象类型A与类型的对象具有 OneToMany 关系 orphanRemoval true cascade CascadeType ALL fetch FetchType EAGER B 我需要 SpringDataRes
  • 如何向 API 提供“回调”? [复制]

    这个问题在这里已经有答案了 我正在读一些模块文档在方法参数的解释中看到一些我不明白的东西 callback 将使用参数调用的回调函数 列表等于callbackargs result 计算完成后 callbackargs 回调函数的附加参数
  • 如何更改 R 中的分辨率(或重新网格)数据

    我有一个数据集 其中包含 lon lat 和涵盖 1961 年至 1970 年的月平均变量 例如温度或降水 该数据集的分辨率为 0 5 x 0 5 度经 纬度 覆盖整个地球 并以 我使用 R 提取数据的 NC 文件 library ncdf
  • 如何将控制台输出写入cpp中的文本文件?

    我正在尝试将控制台数据写入 cpp 中的单独文本文件中 任何人都可以帮我提供示例代码 有多种方法可以做到这一点 您可以使用以下命令从命令行重定向它programname gt out txt 或者你可以使用freopen out txt w
  • 制作不重叠的气泡图

    我目前正在尝试在 Matplotlib 中制作气泡图 其中气泡不重叠 因此将圆圈 气泡包装在图表中 大约像 我认为可能有效的方法 使用 x 1 y 1 绘制第一个数据点 通过计算给定标量值的气泡半径来随机绘制其他数据点以避免重叠 The f
  • 有关 JFreeChart 叠加的帮助

    我遇到了 JFreeChart 重叠图的问题 我正在使用 JFreeChart 1 0 13 我想要做的事情似乎在 JFreeChart 的早期版本中更容易做到 该图显示折线图和条形图 折线图绘制的 Y 轴数据范围为 0 100 范围 条形
  • 如何简化嵌套map调用?

    假设我有一些嵌套函子 例如List Option Int 并需要致电map最内在的一个 现在我正在使用嵌套maps scala gt val opts List Option Int List Some 0 Some 1 opts List
  • nodemailer 无效登录:535 身份验证失败

    我正在尝试在我的节点应用程序中使用nodemailer npm 包 通过联系页面发送电子邮件 它给我这个 535 身份验证失败错误 但我可以向您保证我的电子邮件和密码绝对正确 var express require express var
  • Rails 3 自动资产部署到 Amazon CloudFront?

    Rails 3 1 中是否有可用的 gem 或方法可以自动将资产上传到亚马逊云前端并使用这些资产而不是提供本地托管的资产 我想手动上传编译的资产然后更改 Rails 应用程序配置以使用该资产主机很容易 但是当修改资产时 需要再次手动上传到云
  • 设置 templateLocation 参数时数据流作业运行失败

    当我传递参数暂存 临时和输出 GCS 存储桶位置时 数据流作业失败并出现以下异常 Java代码 final String used Arrays copyOf args args length 1 used used length 1 pr
  • 防止在 Vim 中打开 NERDTree 或 MiniBuffExplorer 窗口内的文件

    我发现自己在 Vim 中打开了错误的窗口 有时是 NERDTree 或 MiniBuffExplorer 这真的让我很失望 我确信这种情况正在发生 因为我的光标错误地聚焦在这些窗口之一内 但是有什么我可以添加到我的 vimrc文件来防止这种
  • Postfix - 如何处理传入的电子邮件? [关闭]

    Closed 这个问题是无关 目前不接受答案 有人知道如何在 postfix 中处理虚拟邮箱的传入电子邮件吗 我正在构建 Web 应用程序 用户通过向应用程序发送电子邮件来添加新内容 每个用户使用的电子邮件地址是自定义的 例如 电子邮件受保
  • 在 Qt 中将 C++ 对象公开给 Javascript

    有什么方法可以将 C 对象 函数公开给 Qt 中 QtWebKit 浏览器内运行的 JavaScript 可以将 ActionScript 对象公开给在 Adob e AIR 中的 WebKit 浏览器内运行的 JS 代码 我正在 Qt 中
  • 在段落中放置表情符号而不影响“行高”

    如何在不影响段落内容的情况下插入表情符号line height不管表情有多大 IE 喜欢 我得到的最接近的是position absolute or vertical align text top 其中没有一个能完成这项工作 p img h
  • jQuery:获取从 中选择的文件名

    这段代码应该可以工作in IE 甚至不要在 Firefox 中测试它 但事实并非如此 我想要的是显示附件的名称 有什么帮助吗
  • Web.config 允许特定用户进行位置访问

    我有一个网络服务器 用户可以从其中下载特定于每个用户的文件 为了确保每个用户只能下载自己的文件 他们必须通过以下方式进行身份验证基本身份验证 因此 对于每个用户 服务器上都有一个 Windows 帐户 该帐户具有对用户特定文件夹的读取权限
  • HTTP 标头 Vary:* 的含义是什么

    据我所知 HTTP 标头Vary指定以逗号分隔的 HTTP 标头列表 在确定请求是缓存命中还是未命中时 缓存需要将这些标头与 URL 一起考虑 如果省略该标头 则表示仅考虑 URL 但是当标题是时会发生什么Vary RFC 2616 14
  • 连接到安全的 websocket

    我正在尝试使用 Jetty 或任何其他库 连接到安全的 websocket 问题是我收到 未找到受信任的证书 错误 我正在使用使用 keytool 生成的自签名证书 可以做什么 import java net URI import java
  • 如何在Spring Boot应用程序中使用多个MongoDB数据库? [复制]

    这个问题在这里已经有答案了 在我的应用程序中 我需要使用两个 MongoDB 数据库 我不知道如何在spring应用程序的application properties文件中添加2个MongoDB数据库 这是我的项目的 application
  • 如何清除最高有效位?

    如何将 int 中的最高有效位从 1 更改为 0 例如 我想将01101更改为0101 编辑 简化 并解释 答案 我在下面给出的答案是多余的 如果你only目标是将最高有效位设置为零 代码的最后一位构造了一个位掩码 其中包含数字中的所有位