java 二进制以及二进制运算

虽然现在很少用到二进制,可是一些源码中会经常遇到,比如:

//HashMap中的hash方法: 
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

这里记录一些二进制知识。

一:负数如何显示其二进制。

比如5的二进制数为:00000000  00000000 00000000 00000101(int 类型占用4个字节,每个字节8位).

那么-5的二进制是多少了。对于负数,这里需要理解反码和补码
1、所谓原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
2、反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外
原码10010= 反码11101 (10010,1为符号码,故为负)
(11101) 二进制= -13 十进制
3、补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
举一例,我们来看整数-5在计算机中如何表示。
假设这也是一个int类型,那么:
1、先取1的原码:00000000 00000000 00000000 00000101
2、得反码: 11111111 11111111 11111111 11111010
3、得补码: 11111111 11111111 11111111 11111011

可以在控制台输出测试:

输出-5的二进制数
System.out.println(Integer.toBinaryString(-5));// 11111111 11111011

二:二进制常用的运算。(^异或运算,与运算&,|运算,左移运算<<,右移运算(有符号)>>,无符号又移>>>)

1.^异或运算。二进制数 相同为0.不同为1;

/**
	 *  ^异或运算。二进制数 相同为0.不同为1; 
	 */
	@Test
	public void testOr(){
		int first=3;//                  0011------------3
		int second=4;//                 0100------------4
		int three=first^second;//       0111------------7
		System.out.println(three);//7
	}

2.&运算。只有都为1时才为1.否则为0

@Test
	/**
	 * 二进制数 只有都为1时才为1.否则为0
	 */
	public void testAnd(){
		int first=12;//-----------------00001100   值为 12
		int second=22;//----------------00010100   值为 22
		int three=first&second;//-------00000100   值为 4
		System.out.println(three);//---4
	}

3.|运算。(参加运算的两个对象只要有一个为1,其值为1。)

@Test  //(参加运算的两个对象只要有一个为1,其值为1。)
	public void testOrAnd(){
		System.out.println(5|2);//7
		System.out.println(Integer.toBinaryString(5));// 00000000 00000000 00000000 00000101
		System.out.println(Integer.toBinaryString(2));// 00000000 00000000 00000000 00000010
		System.out.println(Integer.toBinaryString(7));// 00000000 00000000 00000000 00000111
	}

4.左移运算(<<)

   如果是整数,直接转为二进制数进行左移,低位补0.

  如果是负数。首先也要转为二进制数(通过反码,补码机制)。转移完后,将二进制数加一,取反码。得最终的结果

  下面给的例子是 -5<< 结果为20.

/**
	 * 左移运算(<<)   二进制数向左移动,低位用0补齐
	 * 反码是除符号位(最高位)外取反
	 */
	@Test
	public void testLeftMove(){
		int first=33;//              00100001 值为33
		int two=first<<2;//          10000100 值为132
		System.out.println(two);  //132
		//如果是负数
		//-5 的二进制,先是算5 的二进制       00000000 00000000 00000000 00000101  然后进行取反(除最高位外)
		//-5的反码是                        11111111 11111111 11111111 11111010
		//   补码    反码+1                 11111111 11111111 11111111 11111011
		//-----------------------------------计算 -5<<2的值----------------------------
		//首先-5的补码左移两位,低位补0得:
		//                              11111111 11111111 11111111 11101100
		//然后 减一得:
		//                             11111111 11111111 11111111 11101011
		//最后取反即可:
		//                             00000000 00000000 00000000 00010100  值为20
		  System.out.println(-5<<2);//20
		System.out.println(Integer.toBinaryString(-5));//11111111 11111111 11111111 11111011
	}

5.右移运算(>>).如果是正数,高位补0.如果是负数,高位补1。

    都是先转换为二进制再进行位移运算。如果是负数,也是要借助反码和补码。

/**
	 * 右移(>>) 二进制数整体向右移动。如果是正数,高位补0.如果是负数,高位补1
	 */
	@Test
	public void testRightMove(){
		//-5的二进制       11111111 11111111 11111111 11111011
		//右移1位              11111111 11111111 11111111 111111101
		
		System.out.println(-5>>1);//-3    
		System.out.println(Integer.toBinaryString(-3));//11111111111111111111111111111101
		
		System.out.println(-2147483647>>5);
		System.out.println(Integer.toBinaryString(-2147483647>>5));
		System.out.println(Integer.toBinaryString(-2147483647));
	}

6.无符号的右移运算(>>>)

  即无论是正数还是负数,高位都补0.

下面代码可见>>>运算不再采用补码和反码机制了。不管是正数还是负数,最终都是正数。所以直接    将转移后的二进制转换为正数。如果是负数采用>>>的话,也为正数了。

	/**
	 * 无论正负高位同一补0。
	 */
	@Test
	public void testRightMoveThree(){
		System.out.println(-5>>>2);                               //1073741822
		System.out.println(Integer.toBinaryString(-5));           //11111111 11111111 11111111 11111011
		System.out.println(Integer.toBinaryString(1073741822));//   00111111 11111111 11111111 11111110
	}

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值