切换除最高设置位之外的所有位

Posted

技术标签:

【中文标题】切换除最高设置位之外的所有位【英文标题】:Toggle all bits except after highest set bit 【发布时间】:2021-06-05 03:21:42 【问题描述】:

除了最高设置位之后,如何切换数字的所有位?

例如: 假设需要切换一个 32 位数字。

00000000000000000010011110000100  // Input

00000000000000000001100001111011  // Expected

如何在 java/C++ 中实现这一点??

【问题讨论】:

显示为// Expected 的值不是我所期望的解释toggle all bits of a number except after the highest set bit 并看到// Input:最高位设置也被切换。如果&在尝试改进措辞时,也请在标题中使用不止一位。 【参考方案1】:

我们可以做到以下几点。对于给定的n = 10011110000100

    我们将找到 最小的 2 的幂 v = 100...00 这样v > n。 然后result = n ^ (v - 1)(注意b XOR 1 切换b

发生了什么:

n           =  10011110000100
v           = 100000000000000
v - 1       =  11111111111111
n ^ (v - 1) =  01100001111011

代码:

int n = 0b10011110000100;

int v = 1;

while (v <= n)
  v <<= 1;

int result = n ^ (v - 1);

【讨论】:

【参考方案2】:

你可以这样做:

public static int toggle(int n) 
  int m = n;
  m |= m >>> 1;
  m |= m >>> 2;
  m |= m >>> 4;
  m |= m >>> 8;
  m |= m >>> 16;
  return n ^ m;

重复行的2次方,其目的是在m中设置n的最高有效位以及所有低于它的位,可以用特殊指令替换以查找前导数如果您可以访问此类内容,则归零。

【讨论】:

【参考方案3】:

以下实现说明了 David Eisenstat 在提供任意大整数的语言(例如 Python 或 Ruby)中有效使用 2 的幂。换句话说,这些解决方案不是硬连线的 32 位整数。我用 21000 的输入测试了 Ruby 版本。

红宝石

def toggle(n)
  shift = 1
  m = n
  while (1 << shift) <= n
    m |= m >> shift
    shift <<= 1
  end
  m ^ n
end

Python

def toggle(n):
  shift = 1
  m = n
  while (1 << shift) <= n:
    m |= m >> shift
    shift <<= 1
  return m ^ n

您使用了标签 language-agnostic,所以即使您在问题中提到 C++ 和 Java,我也会相信您的话。

【讨论】:

以上是关于切换除最高设置位之外的所有位的主要内容,如果未能解决你的问题,请参考以下文章

屏蔽除字符串的前 6 位和后 4 位之外的所有数字(长度不同)

Android Gradle 插件组件化中的 Gradle 构建脚本实现 ② ( 组件化基本实现 | Project 相关目录 | 定义组件切换标志位 | 切换插件导入 | 切换设置应用 ID )

Powershell - 删除除最高数字之外的所有内容

在 Gridview 中切换复选框

用于定位回车换行符的正则表达式后跟除 8 位数字和 | 之外的任何内容

我何时需要使用64位Azure函数?