求给定范围数字按位与的结果 Bitwise AND of Numbers Range

本文探讨了在给定的范围内求所有数值按位与的结果。提供了四种不同的解决方案,包括暴力解决、寻找规律后的位操作优化、平移比较以及逐位消除最低位1的方法。

问题:

Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.

For example, given the range [5, 7], you should return 4.

解决:

【题意】将给定的范围m,n,之间的数按位与的结果。假设有m,m1,n1,n四个数,a=m&m1,b=a&n1,c = b & n的结果与m&m1&n1&n的结果相同。

① 暴力解决,超时。

class Solution {
    public int rangeBitwiseAnd(int m, int n) {
        if(m == 0) return 0;
        int res = 2147483647;
        for (int i = m;i <= n ;i ++ ) {
            res = res & i;
        }
        return res;
    }
}

② 从上面可以看出是位操作,要找规律了。

[5,7]:101  110  111 ---->  100

[26,30]:11010  11011  11100 11101 11110 ----> 11000

从上面的例子可以看出,最后数字为1的部分应该是左边的公共部分。所以只需要找到左边的公共部分即可。

建立一个32位都是1的mask,然后每次向左移一位,比较m和n是否相同,不同再继续左移一位,直至相同,然后把m和mask相与就是最终结果。

class Solution { //8ms
    public int rangeBitwiseAnd(int m, int n) {
        int mask = Integer.MAX_VALUE;
        while((m & mask) != (n & mask)){
            mask <<= 1;
        }
        return m & mask;
    }
}

③ 直接平移m和n,每次向右移一位,直到m和n相等,记录下所有平移的次数i,然后再把m左移i位即为最终结果。

class Solution { //8ms
    public int rangeBitwiseAnd(int m, int n) {
        int count = 0;
        while(m != n){
            m >>= 1;
            n >>= 1;
            count ++;
        }
        return (m << count);
    }
}

④ 如果m小于n就进行循环,n&n-1,去掉最低位的1即可。8ms

class Solution {
    public int rangeBitwiseAnd(int m, int n) {
        while(m < n){
            n &= (n - 1);
        }
        return n;
    }
}

转载于:https://my.oschina.net/liyurong/blog/1572911

<think>好的,用户让我介绍一下按位与运算符(&)。首先,我需要回顾之前和用户的对话历史,看看他们之前问过什么。之前用户问过关于`if(cnt&1)continue;`这个代码片段的作用,我详细解释了按位与在这里的应用,特别是判断奇偶数的场景。现在用户直接询问&运算符本身,可能希望更全面地了解它的功能和应用。 接下来,我要分析用户的需。用户可能是在学习编程,特别是C或类似语言,遇到了位运算,想要深入理解按位与的作用。他们可能已经了解基础,但需要更系统的解释,包括原理、应用场景、注意事项等。用户也可能希望看到实际例子,帮助巩固理解。 我需要确保回答结构清晰,分点说明,符合用户之前提到的结构要。要覆盖基本概念、运算规则、应用场景、与逻辑与的区别、注意事项,以及示例代码。此外,用户之前提到过性能优势,比如位运算比取模更快,这点也需要在应用场景中强调。 要注意用户的层次,可能不是初学者,但需要详细的技术解释。需要避免过于简略,同时保持专业但不晦涩。要使用中文,并且数学表达式用$...$格式,独立公式用$$...$$,但用户的问题中没有涉及数学公式,可能不需要太多公式,但如果有必要的话要正确使用。 现在组织内容:首先定义按位与,说明其二进制操作方式。然后详细运算规则,用例子说明不同位的处理。应用场景需要列举几个常见情况,比如掩码操作、奇偶判断、权限管理、性能优化等。和逻辑与的区别要强调操作对象和结果类型的不同。注意事项包括类型限制、运算顺序、可读性等。最后给出示例代码,比如网络掩码、奇偶判断、权限检查等。 需要检查是否有遗漏,比如补码处理、负数情况,之前在注意事项中提到过,这里也要提到。同时注意用户可能对二进制不熟悉,用具体的例子帮助理解。比如用8位二进制数展示按位与的过程。 最后确保语言口语化,避免使用专业术语过多,但保持准确性。比如解释“全1得1,有0得0”这样的口诀帮助记忆。示例代码要简洁,注释清楚,用户之前给出的例子中用了C语言,所以继续使用C的例子可能更合适。</think>以下是关于 **按位与运算符 `&`** 的详细解析: --- ### **1. 基本定义** - **运算符名称**:按位与bitwise AND) - **符号**:`&` - **作用对象**:对两个操作数的 **二进制位** 进行逐位运算 - **核心逻辑**: 全1得1,有0得0 数学表达式: $$ 1 \& 1 = 1,\quad 1 \& 0 = 0,\quad 0 \& 1 = 0,\quad 0 \& 0 = 0 $$ --- ### **2. 运算规则** 假设两个整数 `a` 和 `b`,其二进制表示为: - `a = 5` → 二进制 `0101` - `b = 3` → 二进制 `0011` 运算过程: ``` 0101 (5) & 0011 (3) --------- 0001 (1) ``` 结果:`5 & 3 = 1`(十进制) --- ### **3. 典型应用场景** #### **3.1 掩码操作(Masking)** 提取特定位的值,例如检查第3位是否为1: ```c int value = 0b1010; // 二进制 10 int mask = 0b1000; // 第4位掩码 if (value & mask) { // 第4位为1时执行 } ``` #### **3.2 奇偶性判断** 通过 `x & 1` 快速判断奇偶: - `x & 1 = 1` → 奇数 - `x & 1 = 0` → 偶数 替代效率较低的 `x % 2`。 #### **3.3 权限系统** 用二进制位表示权限状态(如读、写、执行): ```c #define READ 0b001 #define WRITE 0b010 #define EXEC 0b100 int user_permission = READ | WRITE; // 0b011 if (user_permission & WRITE) { // 有写入权限时执行 } ``` #### **3.4 清零特定位** 通过 `&` 和反码将指定位清零: ```c int flags = 0b1111; flags = flags & (~0b0010); // 将第2位清零 → 结果 0b1101 ``` --- ### **4. 与逻辑与(&&)的区别** | 特性 | 按位与 `&` | 逻辑与 `&&` | |--------------|--------------------------|--------------------------| | **操作对象** | 整型(二进制位) | 布尔值(true/false) | | **结果类型** | 整型(按位计算结果) | 布尔型(0或1) | | **短路特性** | 无(所有位必须计算) | 有(左操作数为假则跳过右)| --- ### **5. 注意事项** 1. **类型限制**:仅适用于整数类型(`int`, `char`, `long` 等) 2. **负数处理**:使用补码运算,例如 `-1 & 3 = 3`(因 `-1` 补码为全1) 3. **运算优先级**:低于比较运算符,建议用括号明确优先级,例如 `(a & b) == c` 4. **可读性**:复杂位操作应添加注释说明意图 --- ### **6. 代码示例** ```c // 示例1:网络IP掩码计算 uint32_t ip = 0xC0A80101; // 192.168.1.1 uint32_t subnet = 0xFFFFFF00; // 255.255.255.0 uint32_t network = ip & subnet; // 192.168.1.0 // 示例2:快速判断奇偶 for (int i = 0; i < 10; i++) { if (i & 1) printf("%d 是奇数\n", i); } // 示例3:权限检查 enum Permissions { NONE=0, READ=1, WRITE=2, EXEC=4 }; int user = READ | EXEC; // 0b101 if (user & WRITE) { // 此处不会执行,因 user 无 WRITE 权限 } ``` --- 通过灵活使用 `&`,可以实现高效的低级位操作,常见于系统编程、嵌入式开发、加密算法等场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值