进制、三码及java位运算

了解进制以及原、反、补三码之后有助于更好的理解java位运算

一、进制

  1. 二进制:满2进1,以0b or 0B开头;
int binary = 0b1010;
/* 
	二进制转十进制:从最低位(右边)开始,将每一位乘以2的位数(位数从0开始计)次方,然后求和;
	十进制转二进制:将数不断除以2,直到商为0,然后将每一步得到的余数倒序排列即为所得二进制数; 
*/
  1. 十进制:满10进1;
int decimalism = 1010;
  1. 八进制:满8进1,以数字0开头;
int octonary = 01010;
/*
    八进制转十进制:从最低位(右边)开始,将每一位乘以8的位数(位数从0开始计)次方,然后求和
    十进制转八进制:将数不断除以8,直到商为0,然后将每一步得到的余数倒序排列即为所得八进制数; 
*/
  1. 十六进制:满16进1,以0x or 0X开头表示,A(10)-F(15)
int hexadecimal = 0x1010;
/* 
    八进制转十进制:从最低位(右边)开始,将每一位乘以16的位数(位数从0开始计)次方,然后求和
    十进制转八进制:将数不断除以16,直到商为0,然后将每一步得到的余数倒序排列即为所得十六进制数; 
*/

二、原码、反码、补码

机器数:机器数就是一个带符号的二进制数,符号通常以 ‘0’ 表示正数,以 ‘1’ 表示负数,放置在二进制数的最高位

真值:真值即真正的数值,而机器数的最高位是符号位,即算上符号位的二进制转换为十进制不是计算机真正想表示的数值,所以产生真值的概念,即将带符号位的机器数对应的真正数值为机器数的真值

  • 作用:简单来说,三码的作用是为了使计算机的计算操作由繁化简。计算机识别机器数之后需要辨识符号位,之后再进行运算,这将会十分复杂。而三码的诞生则是使得计算机不需要去辨识符号位而直接将符号位也加入进运算(最终作用是将正数和负数统一起来进行运算,更深入的请自行百度

  • 概念:

    1. 原码:就是符号位的符号加上真值的绝对值 (例如:1111 1111 => 首位1是表示 ‘-’,忽略符号位二进制0111 1111转换十进制为127,则 1111 1111转换为十进制为 -127)
    2. 反码:
      • 正数的反码是其本身
      • 负数的反码是其原码的基础上,符号位不变,其余位取反(例如:1000 0001 => 1111 1110)
    3. 补码:
      • 正数的补码就是其本身
      • 负数的补码是其原码的基础上,符号位不变,其余位取反之后 +1 (例如:1000 0001 => 1111 1111)

三、Java位运算符

  • 了解了上述简单的原理之后,对于java中位运算符的理解就很容易了,java中位运算符主要是优化运算,减少开销。
  • Java运算中,所有参与运算的数都有符号位且运算中都是以补码进行运算(计算机中的运算都是以补码方式进行运算
  1. “&”按位与:两个二进制数相对位置若全为 ‘1’,则结果为 ‘1’,反之为 ‘0’;
int a = 3; // 3的补码: 00000000 00000000 00000000 00000011
int b = 7; // 7的补码: 00000000 00000000 00000000 00000111
int c = a&b; //a&b    00000000 00000000 00000000 00000011
则上述 int c = 3;
  1. “|”按位或:两个二进制数相对位置只要有一个数为 ‘1’,则结果为 ’1‘,反之为 ’0‘;
int a = 3; // 3的补码: 00000000 00000000 00000000 00000011
int b = 7; // 7的补码: 00000000 00000000 00000000 00000111
int c = a|b; //a|b:   00000000 00000000 00000000 00000111
则上述 int c = 7;
  1. “^”按位异或:两个二进制数相对位置若都为 ’1‘,则结果为 ’0‘,反之为 ’1‘;
int a = 3; // 3的补码: 00000000 00000000 00000000 00000011
int b = 7; // 7的补码: 00000000 00000000 00000000 00000111
int c = a^b; //a^b:   00000000 00000000 00000000 00000100
则上述 int c = 4;
  1. “~”按位取反:将一个二进制数每一位的 ‘1’ 变为 ‘0’,‘0’ 变为 ‘1’;
int a =2; // 2的补码:	00000000 00000000 00000000 00000010
int b = ~a; // a取反:    11111111 11111111 11111111 11111101 => a取反之后最高位为1,则是个负数,将负数补码先转为反码再转为原码
			// 补码转反码:11111111 11111111 111111111 111111100
			// 反码转原码:10000000 00000000 00000000 00000011
则上述 int b = -3;
  1. “>>”算数右移:低位溢出,符号位不变,并用符号位补溢出的高位(简单来说就是向右移几位就除几个2)
int a = 1 >> 2; // 1 / 2 / 2 = 0
  1. “<<”算数左移:低位补0,符号位不变(简单来说就是向左移几位就乘以几个2)
int a = 1 << 2; // 1 * 2 * 2 = 4

写在末尾~

// java位运算符在工作业务当中基本很少会用到,个人经验是面试中常见的位运算符的应用只有冒泡算法时的两数置换和二分查找的mid值
		int a = 3;	// a=3      00000000 00000000 00000000 00000011
        int b = 7;	// b=7      00000000 00000000 00000000 00000111
        a=a^b;		// a=a^b=4  00000000 00000000 00000000 00000100
        b=b^a;		// b=b^a=3  00000000 00000000 00000000 00000011
        a=a^b;		// a=a^b=7  00000000 00000000 00000000 00000111
        System.out.println("a => "+a+" ||| b => "+b);	//输出 “ a => 7 ||| b => 3 ”
// 说是减小开销优化运算,其实数据量小基本没有差别
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值