• 位运算 科普


    1 什么是位运算

    程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。比如我们平时使用的java语言中的int类型有32位,那就是由32个位组成。

    /**
     * @ClassName 获得一个int整形的32位二进制表达
     * @Author CabbageDevil
     * @Version 1.0
     **/
    public class bitwiseOperation {
    
        public static void print(int num){
            for(int i=31;i>=0;i--){
                System.out.print((num&(1<<i))==0?"0":"1");
            }
            System.out.println();
        }
        public static void main(String[] args) {
            int num=5;
            print(num);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    通过上面的代码我们可以得出一个int10进制的二进制32位表达,例如
    1的二进制是 00000000000000000000000000000001
    5的二进制是 00000000000000000000000000000101
    最大int整形是2147483647 的二进制是 01111111111111111111111111111111
    最小int整形是-2147483648 的二进制是10000000000000000000000000000000
    也就是2的-31次方到2的31次方-1

    2 关于上面介绍的一些衍生的问题

    问题1: 说是32位,为什么却只有31次方,而不是32次方?
    回答1:

    通过上面我们可以发现,在位运算里面每一位都是前一位的2倍,可以理解成“左移=X2”,所以32位是31位的2倍,也就是4,294,967,296这个数,然而,“int最小”+“0”+“int最大”=4,294,967,296 所以我们一半给了负数,一半给了非负。

    问题2: 继续上面的话题可以看到,正数是比负数少1个的,为什么呢?
    回答2:

    因为有0的存在,0是属于非负的,所以正数需要减少一个

    问题3: 位运算如何取反?

    5的二进制表达是
    00000000000000000000000000000101
    然而-5的则是
    11111111111111111111111111111011
    按取反的逻辑 -5的二进制表达应该是
    11111111111111111111111111111010
    才是正确的但是这里却+了1,因为这样在相互取反的时候计算机底层可以走同一套逻辑不需要进行逻辑分歧,越底层分歧越少,得到的速度也就会越快,
    按上面的逻辑把 -5取反则是
    00000000000000000000000000000100
    +1正好是
    00000000000000000000000000000101 得到了5
    所以这里可以有一个公式

    5取反 = -5 = ~5 + 1
    问题3: 最小数取反?

    在32位里面每个正数都有相对应的负数,那问题来了,最大的负数取反是谁?
    最小int整形是-2147483648 的二进制是10000000000000000000000000000000
    取反就是
    01111111111111111111111111111111 +1
    得到的还是
    10000000000000000000000000000000
    所以最小数取反仍然是它自己
    还有 0 32位就是
    00000000000000000000000000000000
    取反就是
    11111111111111111111111111111111
    再加上1就会变成33位的
    100000000000000000000000000000000,把溢出的弟33位去掉,还是0 所以0按照上面的规则取反还是0 整个底层运算都走的一个计算分支。

  • 相关阅读:
    MySQL高效分页-mybatis插件PageHelper改进
    Java宝典-实战小项目:图书管理系统
    【深度学习目标检测】二十一、基于深度学习的葡萄检测系统-含数据集、GUI和源码(python,yolov8)
    MySQL——内置函数
    Oracle/PLSQL: Lag Function
    Redis6 十二:Redis中的事务
    javascript时间与时间戳互转详解
    LeetCode75-05:压缩字符串
    利用Landsat8 TIRS反演地表温度实例
    带你掌握如何使用CANN 算子ST测试工具msopst
  • 原文地址:https://blog.csdn.net/BCDMW233/article/details/127914221