位运算符(~
, ^
, &
, |
)
~运算符(非)
位运算符, 每一位二进制都只和对应位的二进制进行计算
################ ~运算符(非) ################
十进制数字: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)));
}
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于