详细解析位运算符 {~, ^, &, |} 和移位运算符{<<, >> , >>>}

本贴最后更新于 1651 天前,其中的信息可能已经东海扬尘

位运算符(~, ^, &, |)

~运算符(非)

位运算符, 每一位二进制都只和对应位的二进制进行计算

################  ~运算符(非) ################
十进制数字:2, 二进制:10
结果:十进制数字:-3, 二进制:11111111111111111111111111111101

解析: 将 1 改为 0, 0 改为 1, 二进制:10 前面隐藏了 30 个 0

| 运算符(或)

################  |运算符(或) ################
十进制数字:2, 二进制:10
十进制数字:8, 二进制:1000
结果:十进制数字:10, 二进制:1010

解析: 只要有 1 的位数结果就为 1

^ 运算符(异或)

################  ^运算符(异或) ################
十进制数字:2, 二进制:10
十进制数字:8, 二进制:1000
结果:十进制数字:10, 二进制:1010

解析: 相同的位数结果为 1, 不相同为 0
相同: 即同为1或者同为0

&运算符(与)

################  &运算符(与) ################
十进制数字:2, 二进制:10
十进制数字:8, 二进制:1000
结果:十进制数字:0, 二进制:0

解析: 只有都为 1 的时候才为 1, 其他情况都为 0

移位运算符(<<, >> , >>>)

先普及两个概念,
Integer最大数:十进制数字:2147483647, 二进制:1111111111111111111111111111111
Integer最小数:十进制数字:-2147483648, 二进制:10000000000000000000000000000000

1. 99 移动 1 位

<< 运算符(左移)

################  <<运算符(左移) ################
效果: 二进制后面添加1个0
初始数:十进制数字:99, 二进制:1100011
移动位数:十进制数字:1, 二进制:1
十进制数字:198, 二进制:11000110

解析: 当移动位数为 1 时, 可近似看做是原数乘以 2 的 1 次方(类似 10 进制你后面每加一个 0 就扩大 10 倍), 但是如果位数溢出(超过 Integer 最大数), 则结果就大不一样了(下面有例子)

>> 运算符(右移)

################  >>运算符(右移) ################
效果: 二进制右边去掉5位, 左边补齐32位(按符号位补齐0或1)
初始数:十进制数字:99, 二进制:1100011
移动位数:十进制数字:1, 二进制:1
十进制数字:49, 二进制:110001

解析: 当移动位数为 1 时, 可近似看做是原数除 2 的 1 次方(丢弃余数), 如果除数比被除数还大, 就为 0 了

>>> 运算符(右移忽视符号位)

################  >>>运算符(右移忽视符号位) ################
效果: 二进制右边去掉5位, 并且去掉最前面的符号位(按符号位补齐0或1并且补齐后将符号位改为0)
初始数:十进制数字:-99, 二进制:11111111111111111111111110011101
移动位数:十进制数字:1, 二进制:1
十进制数字:2147483598, 二进制:1111111111111111111111111001110

解析: 去掉右边第一位, 并且将第 32 位(左边数第一位)改为 0

2. -888888888 移动 5 位

################  <<运算符(左移) ################
效果: 二进制后面添加5个0
初始数:十进制数字:-888888888, 二进制:11001011000001001010000111001000
移动位数:十进制数字:5, 二进制:101
十进制数字:1620326656, 二进制:1100000100101000011100100000000

解析: 相当于乘以 2 的 5 次方, 由于整型位数为 32 位, 右边添加完 5 个 0 后为 37 位, 所以将最前面 5 位丢弃, 然后 10100000 前面只剩下 0, 所以最终结果是十进制:160

>> 运算符(右移)

################  >>运算符(右移) ################
效果: 二进制右边去掉5位, 左边补齐32位(按符号位补齐0或1)
初始数:十进制数字:-888888888, 二进制:11001011000001001010000111001000
移动位数:十进制数字:5, 二进制:101
十进制数字:-27777778, 二进制:11111110010110000010010100001110

解析: 相当于除 2 的 5 次方, 右边去掉 5 位, 左边补齐 5 个 1(如果本来第 32 为 0 则补全 0)

>>> 运算符(右移忽视符号位)

################ >>> 运算符(右移忽视符号位) ################
效果: 二进制右边去掉 5 位, 并且去掉最前面的符号位(按符号位补齐 0 或 1 并且补齐后将符号位改为 0)
初始数:十进制数字:-888888888, 二进制:11001011000001001010000111001000
移动位数:十进制数字:5, 二进制:101
十进制数字:106439950, 二进制:110010110000010010100001110

解析: 右边去掉 5 位, 左边补齐 5 个 0

示例源码

package com.wang.math;

/**
 * @Author: WanG
 * @Date: 2019-02-12 15:39
 * @version: v1.0
 * @description: 位运算符
 */
public class 位运算符 {

	
	public static void main(String[] args) {
		printInfo("整型最大数:", Integer.MAX_VALUE);
		printInfo("整型最小数:", Integer.MIN_VALUE);
		位运算();
		移位运算();
	}
	public static void 位运算() {
		int before = 2;
		int before2 = 8;

		System.out.println("\n################  ~运算符(非) ################");
		printInfo(before);
		printInfo("结果:", ~before);

		System.out.println("\n################  |运算符(或) ################");
		printInfo(before);
		printInfo(before2);
		printInfo("结果:", before|before2);

		System.out.println("\n################  ^运算符(异或) ################");
		printInfo(before);
		printInfo(before2);
		printInfo("结果:", before^before2);

		System.out.println("\n################  &运算符(与) ################");
		printInfo(before);
		printInfo(before2);
		printInfo("结果:", before&before2);
	}

	/**
	 * 将符号位直接移动
	 * 当移动位数为1时, 接近乘以二和除2的效果
	 * @author wangq 2019-02-12 15:56
	 * @param
	 * @return
	 */
	public static void 移位运算() {
		int before = -99;
		int before2 = 5;

		System.out.println("\n################  <<运算符(左移) ################");
		System.out.println("效果: 二进制后面添加" + before2 + "个0");
		printInfo("初始数:", before);
		printInfo("移动位数:", before2);
		printInfo(before<<before2);


		System.out.println("\n################  >>运算符(右移) ################");
		System.out.println("效果: 二进制右边去掉" + before2 + "位, 左边补齐32位(按符号位补齐0或1)");
		printInfo("初始数:", before);
		printInfo("移动位数:", before2);
		printInfo(before>>before2);

		System.out.println("\n################  >>>运算符(右移忽视符号位) ################");
		System.out.println("效果: 二进制右边去掉" + before2 + "位, 并且去掉最前面的符号位(按符号位补齐0或1并且补齐后将符号位改为0)");
		printInfo("初始数:", before);
		printInfo("移动位数:", before2);
		printInfo(before>>>before2);

	}

	/**
	 * 打印
	 * @author wangq 2019-02-12 15:40
	 */
	private static void printInfo(int num) {
		printInfo("", num);
	}

	/**
	 * 打印
	 * @author wangq 2019-02-12 15:40
	 */
	private static void printInfo(String msg, int num) {
		System.out.println(String.format(msg + "十进制数字:%s, 二进制:%s", num, Integer.toBinaryString(num)));
	}
}
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖
  • 算法
    388 引用 • 254 回帖 • 22 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...