位运算符 & | ^ ~ << >> >>> 计算机底层存储运算科普(反码...)

 

 进制及转换

计算机中的数据不同于人们生活中的数据,人们生活采用十进制数,而计算机中全部采用二进制数表示,它只包含0、1两个数,逢二进一,1+1=10。每一个0或者每一个1,叫做一个bit(比特)。

下面了解一下十进制和二进制数据之间的转换计算。

1、 十进制转二进制

十进制整数转换成二进制采用“除2倒取余”,十进制小数转换成二进制小数采用“乘2取整”。

十进制转八进制、十六进制的思路与十进制转二进制一样。

2、二进制转十进制

二进制转十进制采用按权相加法

二进制转换成八进制的方法是,取三合一法,即从二进制的小数点为分界点,向左(或向右)每三位取成一位。

二进制转换成十六进制的方法是,取四合一法,即从二进制的小数点为分界点,向左(或向右)每四位取成一位。

更多转换细节,可以查阅一些资料,参考地址:计算机基础进制转换(二进制、八进制、十进制、十六进制)_daixiangcn的博客-CSDN博客_计算机进制

另外介绍一下,快速进制转换器:十进制转八进制| 10进制转8进制 | 在线进制转换

计算机中是以二进制补码进行存储的,正数的原码、反码、补码都是一样,负数的补码是原码的反码再加1,这样可以减法运算可以使用加法器实现,符号位也参与运算二进制的最高位为符号位0为正,1为负,以8位来算,最高位为符号位,其余7位表示数值),取反码与符号位无关。

基础定义:

 原码:
 ​
     * 就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其他位存放该数的二进制的绝对值。
 ​
     * 通过一个字节,也就是8个二进制位表示+7和-7
 ​
     * 0(符号位) 0000111
 ​
     * 1(符号位) 0000111
 ​
 反码:
 ​
     * 正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位不变。
 ​
 补码:
 ​
     * 正数的补码与其原码相同;负数的补码是在其反码的末位加1。
 原码=正数的二进制
 补码=  反码 + 1
 反码=    -(原码) 

小贴士:

计算机中的源码,是十进制数转换为计算机0、1表示的原本真实字节码数据;而反码和补码的出现则是为了负数的计算而生的。所以,计算机底层参与运算的都是补码形式。

&按位与两数同位对比,有0则为0
|按位或两数同位对比,有1则为1
^按位异或两数同位对比,不同为1,相同为0
~按位取反针对一个数,操作数的每一位都取反
<<按位左移针对一个数,操作数的每位向左移动指定位数,最高位丢弃,尾部空位补0(相当于乘以2的n次方)
>>按位右移针对一个数,操作数的每位向右移动指定位数,头部空位补符号位数,移除部分丢弃
>>>无符号右移

针对一个数,操作数的每位向右移动指定位数,无论符号数头部都补0,移除部分丢弃

 

public class demo {
	/**
	 * 位运算符 & | ^ ~ << >> >>>
	 * 
	 * @author admin
	 *
	 */
	public static void main(String[] args) {
		
		/**
		 * 
		 */
		
		System.out.println(3 & 4); // 0	 按位与	  两数同位对比,有0则为0
		System.out.println(3 | 4); // 7    	 两数同位对比,有1则为1
		System.out.println(3 ^ 4); // 7 	 两数同位对比,不同为1,相同为0
		System.out.println(~7);    // -8	 针对一个数,操作数的每一位都取反
		

		// 左移 :无论正负数,后面补零。
		System.out.println(12 << 2); // 48 12<<2 12*2^2
		// 0000 1100---> 0011 0000
		System.out.println(33 << 3); // 264
		System.out.println(-15 << 4); // 16
		// 1111 0001---> 0001 0000

		// 右移
		System.out.println(2 >> 2); // 0
		// 0000 0010--->0000 0000
		System.out.println(-2 >> 2); // -1
		// 1111 1111 1111 1111 1111 1111 1111 1110-->1111 1111 1111 1111 1111 1111 1111 1111
		System.out.println(-9 >> 3); // -2
		// 1111 1111 1111 1111 1111 1111 1111 0111-->1111 1111 1111 1111 1111 1111 1111 1110

		// 无符号右移,仅针对32位或64位
		System.out.println(3 >>> 1); // 1
		// 0000 0000 0000 0000 0000 0000 0000 0011--->0000 0000 0000 0000 0000 0000 0000 0001

		System.out.println(-3 >>> 1); // 2147483646
		// 1111 1111 1111 1111 1111 1111 1111 1101--->0111 1111 1111 1111 1111 1111 1111 1110
		
		
		// !!!! int类型 4byte=4*8bit
	}

	/***
	 * 有符号右移>>(若正数,高位补0,负数,高位补1) 无符号右移>>>(不论正负,高位均补0)
	 * 
	 * 理解 有符号右移是区分正负的位操作。即你理解的乘以或除以2的n次方符号也被带上了。 但这是十进制的概念。
	 * 无符号右移是单纯的位操作。抛除符号的概念转换为位的移动。从每个位表达的不同信号含义来讲,这种操作用处很广。
	 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值