按位运算符简单地翻转整数中的所有位?
我必须翻转整数的二进制表示形式中的所有位。给定:
10101
输出应该是
01010
当与整数一起使用时,完成此操作的按位运算符是什么?例如,如果我正在编写像 int FlipBits(int n);
这样的方法,那么主体中会包含什么?我只需要翻转数字中已经存在的内容,而不是整数中的所有 32 位。
I have to flip all bits in a binary representation of an integer. Given:
10101
The output should be
01010
What is the bitwise operator to accomplish this when used with an integer? For example, if I were writing a method like int flipBits(int n);
, what would go in the body? I need to flip only what's already present in the number, not all 32 bits in the integer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
~
一元运算符是按位求反。如果您需要的位数少于int
所容纳的位数,那么您需要在事后用&
屏蔽它。The
~
unary operator is bitwise negation. If you need fewer bits than what fits in anint
then you'll need to mask it with&
after the fact.只需使用按位非运算符
~
即可。要使用 k 个最低有效位,请将其转换为正确的掩码。
(当然,我假设您至少需要 1 位,这就是掩码从 1 开始的原因)
正如 Lưu Vĩnh Phúc 所建议的,可以将掩码创建为
(1 << k) - 1
而不是使用循环。Simply use the bitwise not operator
~
.To use the k least significant bits, convert it to the right mask.
(I assume you want at least 1 bit of course, that's why mask starts at 1)
As suggested by Lưu Vĩnh Phúc, one can create the mask as
(1 << k) - 1
instead of using a loop.有多种方法可以使用操作来翻转所有位
There is a number of ways to flip all the bit using operations
更快更简单的解决方案:
faster and simpler solution :
好吧,因为到目前为止,只有一个解决方案可以给出“正确”的结果,而这确实不是一个好的解决方案(使用字符串来计算前导零?这会在我的梦想中困扰我;))
所以这里我们使用一个不错的干净解决方案应该有效 - 虽然还没有彻底测试它,但你明白了要点。确实,java没有无符号类型对于这类问题来说是非常烦人的,但它应该是相当有效的(如果我可以这么说,比从数字中创建一个字符串要优雅得多)
Well since so far there's only one solution that gives the "correct" result and that's.. really not a nice solution (using a string to count leading zeros? that'll haunt me in my dreams ;) )
So here we go with a nice clean solution that should work - haven't tested it thorough though, but you get the gist. Really, java not having an unsigned type is extremely annoying for this kind of problems, but it should be quite efficient nonetheless (and if I may say so MUCH more elegant than creating a string out of the number)
一条线解决方案
One Line Solution
如果您只想翻转整数中“使用”的位,请尝试以下操作:
If you just want to flip the bits which are "used" in the integer, try this:
一行(在 Javascript 中 - 您可以转换为您最喜欢的编程语言)
解释:
mask
:用于过滤掉有效位计数之前的所有前导位(nBits - 见下文)如何计算有效位算不算?
例如:
000000000
1
返回 1000
1000001
返回 700000
10101
返回 5One liner (in Javascript - You could convert to your favorite programming language )
Explanation:
mask
: For filtering out all the leading bits before the significant bits count (nBits - see below)How to calculate the significant bit counts ?
Ex:
000000000
1
returns 1000
1000001
returns 700000
10101
returns 5我必须看一些例子才能确定,但由于二进制补码运算,您可能会得到意想不到的值。如果数字有前导零(如 26 的情况),~ 运算符将翻转它们以使其成为前导零 - 导致负数。
一种可能的解决方法是使用 Integer 类:
我现在没有设置 java 环境来测试它,但这是一般的想法。基本上只需将数字转换为字符串,切断前导零,翻转位,然后将其转换回数字。 Integer 类甚至可能有某种方法将字符串解析为二进制数。我不知道这是否是问题需要解决的方式,而且它可能不是最有效的方法,但它会产生正确的结果。
编辑:polygenlubricants 对这个问题的回答也可能有帮助
I'd have to see some examples to be sure, but you may be getting unexpected values because of two's complement arithmetic. If the number has leading zeros (as it would in the case of 26), the ~ operator would flip these to make them leading ones - resulting in a negative number.
One possible workaround would be to use the Integer class:
I don't have a java environment set up right now to test it on, but that's the general idea. Basically just convert the number to a string, cut off the leading zeros, flip the bits, and convert it back to a number. The Integer class may even have some way to parse a string into a binary number. I don't know if that's how the problem needs to be done, and it probably isn't the most efficient way to do it, but it would produce the correct result.
Edit: polygenlubricants' answer to this question may also be helpful
我有另一种方法来解决这种情况,
它是使用 XOR 来获取补码位,为了补码,我们需要将数据与 1 进行异或,例如:
101 XOR 111 = 010
(111 是“密钥”,它由搜索数据的“n”平方根)
如果您使用〜(补码),结果将取决于其变量类型,如果您使用int,则它将被作为32位处理。
I have another way to solve this case,
It is using XOR to get the complement bit, to complement it we need to XOR the data with 1, for example :
101 XOR 111 = 010
(111 is the 'key', it generated by searching the 'n' square root of the data)
if you are using ~ (complement) the result will depend on its variable type, if you are using int then it will be process as 32bit.
由于我们只需要翻转整数所需的最少位(假设 50 是 110010,反转后,它变成 001101,即 13),因此我们可以一次将各个位从 LSB 反转到 MSB,并继续移位位向右并相应地应用 2 的幂。下面的代码完成所需的工作:
As we are only required to flip the minimum bits required for the integer (say 50 is 110010 and when inverted, it becomes 001101 which is 13), we can invert individual bits one at a time from the LSB to MSB, and keep shifting the bits to the right and accordingly apply the power of 2. The code below does the required job:
openJDK 的实现,Integer.reverse():
根据我在笔记本电脑上的实验,下面的实现速度更快:
不确定背后的原因是什么 - 因为它可能取决于 java 代码如何解释为机器代码......
The implementation from openJDK, Integer.reverse():
Base on my experiments on my laptop, the implementation below was faster:
Not sure what's the reason behind it - as it may depends on how the java code is interpreted into machine code...
可以通过一个简单的方法来完成,只需从值中减去数字即可
当所有位都等于 1 时获得。
例如:
号码:给定号码
值:所有位都设置为给定数字的数字。
翻转的数字 = 值 – 数字。
例子 :
数量 = 23,
二进制形式:10111
翻转数字后的数字将为:01000
值:11111 = 31
我们可以在 O(1) 时间内找到固定大小整数的最高有效设置位。为了
下面的代码示例适用于 32 位整数。
It can be done by a simple way, just simply subtract the number from the value
obtained when all the bits are equal to 1 .
For example:
Number: Given Number
Value : A number with all bits set in a given number.
Flipped number = Value – Number.
Example :
Number = 23,
Binary form: 10111
After flipping digits number will be: 01000
Value: 11111 = 31
We can find the most significant set bit in O(1) time for a fixed size integer. For
example below code is for a 32-bit integer.