Java基础进制转换和位移操作总结

本文深入探讨了Java中的进制转换方法,包括二、八、十六进制与十进制之间的转换,以及有符号数和无符号数的概念。详细讲解了原码、反码、补码的转换规则,同时介绍了位运算符(如按位与、或、异或、取反、左移、右移)的操作原理和实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.常见进制的组成

二进制:由0和1组成

八进制:由0,1,2,3,4,5,6,7组成

十六进制:由0到9,外加A,B,C,D,E,F六个英文字母(不分大小写)组成,A相当于十进制中的10,B是11,C是12,D是13,E是14,F是15

2.表达形式

二进制的写法:以0b开头

八进制的写法:以0开头

十六进制的写法:以0x开头

3.计算方法

规则:是几进制则满几进一,例如十进制是满十进一,二进制则是满二进一,八和十六进制同理。

例如:

		二进制:0b11110+0b111001=? 
		
					1 1 1 1 0 
			+   1 1 1 0 0 1            
			----------------------
			  1 0 0 1 0 0 0 0
			= 0b10010000
		    
		    八进制:01234+05678=?

			  	1 2 3 4
			+	5 6 7 8
			----------------------	
				7 1 3 4
			= 07134

		    十六进制:0x3ac+0x8bf6=?  

					3 a c			            	   3    10  12
			+     8 b f 6			=》同等于   	 +  8  11   15  6        =》 用十六进制表示为:0x8fa2   
			----------------------	              ----------------------
												    8  15   10  2
			=0x8fa2	   

4.任意进制转换为十进制的方法

概念说明:

  1. 系数:是指每一位上的数,例如十进制123,个位上的系数为3,十位上的系数为2,百位上的系数为1,其他进制同理;
  2. 基数:是几进制基数就是几,例如二进制的基数为2,十进制的基数为10;
  3. 权:一个数从右往左数,位置从0开始数,每一位数所在的位置就是该位的权,例如:十进制1234567,7的权是0, 6的权是1,5的权是2,4的权是3,类似于String的index;

具体方法(规律):任意进制转换为十进制都等于“ 这个数的每一位的系数乘以基数的权次幂的和 ”。

例如:

				十进制->十进制:456 = 6*10^0 + 5*10^1 + 4*10^2 = 6+50+400 = 456
			
				二进制->十进制:0b456 = 6*2^0 + 5*2^1 + 4*2^2 = 6+10+16 = 32

				八进制->十进制:0456 = 6*8^0 + 6*8^1 + 4*8^2 = 6+48+256 = 310

				十六进制->十进制:0x456 = 6*16^0 + 5*16^1 + 4*16^2 = 6+80+1024 = 1110

5.十进制转换为二、八、十六进制

具体方法(规律):十进制转换为任意进制,都是除以基数取余,直到商为0,然后对余数进行反转

例如:

			十进制100->二进制     
				
						2|___100__                      0    ∧
					       2 |___50____                 0    ∧
					         2 |____25_____             1    ∧
						    	2 |____12____           0    ∧    
									2|____6___          0    ∧
							  			2|____3____	    1    ∧	
							     			2|___1____	1    ∧
								  				 0
			描述:把所有余数进行组合->0010011->进行反转->1100100,也就是从下往上进行组合的顺序,所以最后表示结果为:0b1100100
			
			
			十进制100->八进制    
	
					    8|___100__	  				    4    ∧			
					       8 |___12____                 4    ∧   
					         8 |____1_____              1    ∧
									0
		    描述:把所有余数进行组合->441->进行反转->144,也就是从下往上进行组合的顺序,所以最后表示结果为:0441
			

			十进制200->十六进制     

					   16|___200__	                    8    ∧    
					     16  |___12____                 12   ∧   			       
							  	 0	
			描述:把所有余数进行组合->8c(12用字母c来代替)->进行反转->c8,也就是从下往上进行组合的顺序,所以最后表示结果为:0xc8	 

6.二进制中的有符号数和无符号数

数据有正负之分的属于有符号数,没有正反之分的属于无符号数

例如:1和-1等属于有符号数(数字有正负之分),表示正一和负一,类似文件之类的数据,视频和音频等属于无符号数,没有正负之分

有符号数由两部分(符号位+数值位)组成:

  1. 符号位:正为0,负为1,用最高位(从左往右,第一位)来表示符号位;
  2. 数值位:符号位之后的就为数值位

7.有符号数的原码、反码和补码

计算机中,有符号数是以补码的形式进行存储,以原码的形式展示出现,正数的原码、反码和补码都是一样的,负数的原
码、反码和补码是不一样的,存储和展示的时候会对其进行相互转换。

注:(平常其他进制转化为二进制时,如(除2取余),转换之后都是以原码的形式来体现的)

转换规则如下:

			原码->反码->补码
			
			原码->反码:符号位不变,其他位0变1 1变0

			反码->补码:反码加1得到补码

			反之:补码->反码->原码

			补码->反码:补码减一得到反码

			反码->原码:符号位不变,其他位0变1 1变0

例如:

		正数7的原码为:0b00000000 00000000 00000000 00000111(int类型占4个字节,1个字节是8位),

		符号位为0,正数原反补码一样,所以反码和补码也为0b00000000 00000000 00000000 00000111,

		而负数-7的原码为:0b10000000 00000000 00000000 00000111,存储时会将原码转换为补码进行存储,

		由-7原码可得:

			原码->反码:0b11111111 11111111 11111111 11111000 ,得到反码(符号位不变,其他位0变1 1变0)

			再由反码->补码:0b11111111 11111111 11111111 11111001(反码加1得到补码)
	
		所以 7在内存中存储的值0b00000000 00000000 00000000 00000111 (补码形式)

		    -7在内存中存储的值0b11111111 11111111 11111111 11111001 (补码形式)

8.位运算(对数字计算而言)符号

  1. &:按位与
  2. | :按位或
  3. ^:按位异或
  4. ~:按位取反
  5. <<:左移
  6. >>:右移
  7. >>>:无符号右移

在进行位运算的时候,需要先把数据先转换成二进制位,并且都是以二进制的补码形式进行操作

例如:

			4的二进制为:0b00000000 00000000 00000000 00000100(正数原反补码都一样,在此表示为补码形式)

			6的二进制为:0b00000000 00000000 00000000 00000110(正数原反补码都一样,在此表示为补码形式)

			(1)按位与规则:两个同时为1,则为1,否则为0

				4 & 6 = 0b00000000 00000000 00000000 00000100(补码形式) = 0*2^0+0*2^1+1*2^2 =  4(在此表示为原码形式)

			(2)按位或规则:一个为1,则为1,否则为0

				4 | 6 = 0b00000000 00000000 00000000 00000110(补码形式) = 0*2^0+1*2^1+1*2^2 = 6(在此表示为原码形式)

			(3)按位异或规则:两个不一样的时候为1,否则为0

				4 ^ 6 = 0b00000000 00000000 00000000 00000010(补码形式) = 0*2^0+1*2^1 = 2(在此表示为原码形式)

			(4)按位取反规则:0变1,1变0

				~4 = 0b11111111 11111111 11111111 11111011(补码形式),可以看出最高位1,所以结果为负数,

				需要把结果由补码转为反码,然后反码转为原码即可得出最后结果,因此:

					(1)0b11111111 11111111 11111111 11111011(补码形式)
						
			  		(2)转为反码:0b11111111 11111111 11111111 11111010(反码形式)

					(3)由反码转为原码:0b10000000 00000000 00000000 000000101(原码形式) = -(1*2^0+0*2^1+1*2^2)=-(1+4)=-5

				~6同理,结果为:~6 = 0b11111111 11111111 11111111 11111001(补码形式)

					-> 转反码: = 0b11111111 11111111 11111111 11111000(反码形式)
					
					-> 转原码: = 0b10000000 00000000 00000000 00000111(原码形式) = -(1*2^0+1*2^1+1*2^2)=-(1+2+4)=-7

			(5)按位左移规则:操作数乘以2的n次幂,n为左移的位数

				具体操作方式:左移几位,就将二进制位向左移动几位,舍弃移除的位数,然后右边空出的位用0填补

				例如4的二进制为:0b00000000 00000000 00000000 00000100(正数原反补码都一样,在此表示为补码形式)

				4 << 6 

				->将4的二进制的补码左移6位-> 0b00000000 00000000 00000001 00->右边空出的位补0

				-> 0b00000000 00000000 00000001 00000000->判断符号位是0还是1

				->符号位(最高位)为0是正数,所以不用进行码转换操作(正数原反补码都一样,在此表示为原码形式)

				->  = 0*2^0+0*2^1+0*2^2+0*2^3+0*2^4+0*2^5+0*2^6+0*2^7+1*2^8 = 2^8= 256(也就是4乘以2的6次方)

			(6)按位右移规则:操作数(正数)除以2的n次幂,n为右移的位数

				具体操作方式:右移几位,就将二进制位向右移动几位,舍弃移除的位数,然后左边空出的位由符号位来决定,

					      符号位为0,则用0填补,符号位为1,则用1填补
				
				例如4的二进制为:0b00000000 00000000 00000000 00000100(正数原反补码都一样,在此表示为补码形式)

				4 >> 6 

				->将4的二进制的补码右移6位-> 0b00000000 00000000 00000000 00

				->判断符号位是0还是1

				->符号位(最高位)为0(右移 符号位为0,则用0填补,符号位为1,则用1填补)

				->0b00000000 00000000 00000000 00000000->最高位为0是正数,所以不用进行码转换操作(正数原反补码都一样,在此表示为原码形式)->

				->  = 0 (也就是4除以2的6次方)
			
			对负数进行左移或者右移操作方式如下:

				规则:因为位移操作都是以二进制的补码形式进行操作的,所以首先需要得到负数的原码之后,再求的补码,才能对其进行位操作。
		
				例如-4的二进制为:0b10000000 00000000 00000000 00000100(在此表示为原码形式)

						  原码->反码:0b11111111 11111111 11111111 11111011

						  反码->补码:0b11111111 11111111 11111111 11111100	
		
				求得-4的二进制补码形式为:0b11111111 11111111 11111111 11111100

				(1)-4 << 6 

				   ->将-4的二进制的补码左移6位

				   ->0b11 11111111 11111111 11111100->判断符号位是0还是1->符号位(最高位)为1

				   ->0b11111111 11111111 11111111 00000000(补码形式)->最高位为1是负数,所以需要转换成反码的形式
				
				   ->0b11111111 11111111 11111110 11111111(反码形式)

				   ->0b10000000 00000000 00000001 00000000(原码形式)

				   -> = -(0*2^0+0*2^1+0*2^2+0*2^3+0*2^4+0*2^5+0*2^6+0*2^7+1*2^8) = -1*2^8 = -256 (也就是-4乘以2的6次方)
				
				(2)-4 >> 6 

				   ->将-4的二进制的补码右移6位-> 0b11111111 11111111 11111111 11->判断符号位是0还是1->符号位(最高位)为1

				   ->(右移 符号位为0,则用0填补,符号位为1,则用1填补)

				   ->0b11111111 11111111 11111111 11111111(补码形式)->最高位为1是负数,所以需要转换成反码的形式
				
				   ->0b11111111 11111111 11111111 11111110(反码形式)

				   ->0b10000000 00000000 00000000 00000001(原码形式)

				   -> = -(1*2^0) = -1

					
			(7)按位无符号右移:
		
				具体操作方式与右移规则一样,与右移操作符的区别在于,右移的空位有符号位来决定,符号位为0,则用0填补,符号位为1,则用1填补,而无符号右移,

				左边空出的位则全都由0来填补,不由符号位决定
					           
				例如-4 >>> 6 

				   ->将-4的二进制位右移6位-> 0b11111111 11111111 11111111 11

				   ->(空位由0来填补)

				   -> 0b00000011 11111111 11111111 11111111(补码形式)

				   ->最高位为0是正数,所以不用进行码转换操作(正数原反补码都一样,在此表示为原码形式)

				   -> = 1*2^0+1*2^1+1*2^2+1*2^3+1*2^4+1*2^5+1*2^6+...+1*2^25 = 67108863

由此可见,对于正数来说,右移和无符号右移是没区别的,对于负数有些是不能用算术右移来实现除法(例如-32 >> 2 就符合除法规则结果为-8)

以上是最近学习位运算的一些总结,如上述代码有错误之处,还请指出,再次感谢!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值