你以为你真的了解二进制吗?详解JDK中的二进制骚操作

目录:

[图片上传失败…(image-98c3f8-1616855044646)]

要求十进制转二进制,首先我们想到的是除2求余法,比如数字15,如下,不断的除以2,一直到0为止,最后将余数倒序排列就是该数的二进制表示

15/2 = 7 --------余1
7/2  = 3 --------余1
3/2  = 1 --------余1
1/2  = 0 --------余1

所以15的二进制表示就是1111,再举一例,520的二进制表示

520/2 = 260 -------余0
260/2 = 130 -------余0
130/2 = 65 --------余0
65/2  = 32 --------余1
32/2  = 16 --------余0
16/2  = 8  --------余0
8/2   = 4  --------余0
4/2   = 2  --------余0
2/2   = 1  --------余0
1/2   = 0  --------余1

余数倒序排列就是1000001000,所以520的二进制表示就是1000001000,那么把上述的算法用作代码写出来是怎么样的呢?

第一个版本

Java代码将上述过程表达出来如下

public static String toBinary(int i){
    StringBuilder sb = new StringBuilder();
    while (i > 0){
        //i%2求余 比如15%2=1
        sb.append(i % 2);
        //求余之后除以2再赋值给i
        //注意,i是整型,所以小数会抹去,比如15/2=7,而不是7.5
        i = i / 2;
    }
    //将最后的结果逆序后再返回
    return sb.reverse().toString();
}

验证一下

System.out.println(toBinary(520));//我们自己写的
System.out.println(Integer.toBinaryString(520));//JDK自带的

看看结果,输出是一样的说明验证通过

1000001000
1000001000

但是对于追求极致性能的我们来说并不满足上面的转换,因为求余操作符%的性能并没有位运算高,所以我们改成位运算,所以就出现了下面的第二个版本

第二个版本

第二个版本主要引入位运算为后面JDK的实现做好基础。

public static String toBinary1(int i){
    StringBuilder sb = new StringBuilder();
    while (i > 0){
        //任何数与1做与运算,
        // 结果是0说明是偶数,任何偶数与2相除都余0
        // 结果是1说明是奇数,任何奇数与2相除都余1
        sb.append(i & 1);
        //求余之后除以2再赋值给i,i >> 1 表示 i / 2^1,
        //注意,i是整型,所以小数会抹去,比如15/2=7,而不是7.5
        i = i >> 1;//也可以写成 i >>= 1
    }
    return sb.reverse().toString();
}

重点说明i & 1

我们知道 i % 2 是除以2后的求余操作,比如 15 % 2 = 1 ,那么i & 1运算又是什么鬼?从上文可知,那么我们来证明下面的公式

i % 2 = i & 1

对不熟悉位运算的同学可能一头雾水,这都是些啥符号,&表示二进制与运算,运算法则为全1得1,有0得0,举个例子

# 15 的二进制位1111 , 1的二进制位0001
15 & 1 = 1111 & 0001 = 1

i & 1只能说明奇偶性,只看i的最后一位,如果最后一位是1说明是奇数,是0说明是偶数,这个怎么证明?先看二进制量表,所有的整数都可以从量表中的数字加起来表示,比如15 = 8+4+2+1,每位上都有,所以15的二进制是1111,二进制就是这么神奇,无论什么整数你都可以从下面的量表中找出数字加起来表示

[图片上传失败…(image-c413a8-1616855044646)]

扯远了,回来看一下量表,只有最低位2^0=1这个数字是奇数是吧,其他所有的数字全都是偶数,那么偶数加偶数还是偶数,偶数加1就是奇数,奇数加1?根本不存在这种情况,因为只有一个1,偶数变成奇数已经用掉了,比如3 = 2 + 1 = 011 (二进制) ,4 = 4 &#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码狂魔v

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值