Java查找最右不同位代码循环仅运行到i=3的原因及错误解析
代码存在的错误
- 第一,
res的移位逻辑完全错误。你当前代码写的是res = res << i,是把上一轮的res再左移i位,这会导致res的实际值为1 << (0+1+2+...+i),远大于你预期的对应第i位的掩码1 << i,res会快速溢出int的取值范围,出现不符合预期的正负值,导致位与结果提前出现差异。 - 第二,Java标准库的数学类是
Math,首字母必须大写,你写的小写math会直接报编译错误,无法运行。 - 第三,循环条件设计冗余。int类型最多只有32位有效位,你完全不需要循环到
Math.max(m,n)次,最多循环32次就能覆盖所有可能的情况,当max值很大时会严重浪费性能。
异常运行原因说明
你传入的参数52的二进制是 00110100,4的二进制是 00000100,预期最右不同位是第5位(从1开始数)。你的代码实际运行流程如下:
- 初始res=1,max值为52
- i=0:res = 1 << 0 = 1,两个数和1做位与都得0,继续
- i=1:res = 1 << 1 = 2,两个数和2做位与都得0,继续
- i=2:res = 2 << 2 = 8,两个数和8做位与都得0,继续
- i=3:res = 8 << 3 = 64,此时int溢出逻辑触发,位与结果出现不符合预期的不一致,就会直接跳出循环,输出i+1=4,和预期结果不符。
修正后代码
逐位检查版本
package Bitwise; public class rightmostDifferentBit { static void findBit(int n, int m) { // 最多循环32次即可覆盖int所有位 for(int i = 0; i < 32; i++) { int mask = 1 << i; if((n & mask) != (m & mask)) { System.out.println(i+1); return; } } // 所有位都相同的情况返回-1 System.out.println(-1); } public static void main(String[] args) { findBit(52,4); } }
位运算优化版本(无需循环)
static void findBit(int n, int m) { int xor = n ^ m; // 异或结果为0说明所有位都相同 if(xor == 0) { System.out.println(-1); return; } // 计算异或结果尾随0的个数+1就是最右不同位的位次 System.out.println(Integer.numberOfTrailingZeros(xor) + 1); }
内容的提问来源于stack exchange,提问作者abhay saxena
相关产品推荐
相关产品推荐

