二进制浅析

二进制浅析

起因

昨天在学习数据结构中的赫夫曼编码,进行解码和编码用到了二进制的存储机制。作为半路出家的我,是没有系统学过计算机组成的,对二进制很陌生。在听课的途中,老师因为是主要讲数据结构对二进制的知识也是一提就过了。这就导致关于二进制的那部分代码令我很头疼。故花费一点时间深入的了解一下二进制。

原码,反码,补码

这里的定义啥的就按照我理解的大白话来。

原码 :一个十进制正数转化为二进制就是这个正数的原码,一个十进制负数,它的绝对值转化为二进制然后在其高位补1就是这个负数的原码

例如:88 的原码是1011000 -88 的原码是11011000

反码 :正数的反码就是其本身,负数的反码码就是除去其最高位(符号位)之外全取反

例如: 88 的反码是1011000 -88 的反码是 1100111

补码 :正数的补码还是它本身,负数的补码是其反码加1

例如: 88 的补码是1011000 -88 的补码是 10101000

通过定义来看,正数的三个码都是相同的,负数的原码比正数多一个高位1,反码除高位1剩下的位全取反,补码反码加1

parseInt和toBinaryString

首先我不分析这两个方法的源码,一是我没这个实力,二是这篇文章主要还是看二进制的内容,这里就是看这两个方法在进行二进制转化时的一些问题。

这两个方法都是在包装类Integer中的静态方法。
对于toBinaryString,它的作用是将十进制数字转化为二进制字符串
这里先看一段测试代码

String s1 = Integer.toBinaryString(88);
System.out.println(s1); // 结果 - > 1011000
String s2 = Integer.toBinaryString(-88);
System.out.println(s2); // 结果 - > 11111111111111111111111110101000

先看s1结果是1011000看之前的例子这个结果是正确的
再看s2结果是11111111111111111111111110101000一共是32位一个整数是4个字节也就是32位是没问题的截取后八位(有效位)10101000可以发现这是-88的补码

这样就能发现toBinaryString的结果不论是转化正数还是负数都是转为二进制的补码,但是正数前面的无效多余的0会被省略

对于parseInt我主要研究的时它的将2进制字符串转化为Integer的重载。

byte i = (byte)Integer.parseInt("10101000", 2);
System.out.println(i); // -> -88

我们将10101000(-88的补码)传入得到的结果是-88
这样看parseInt这个方法识别的也是补码

结论: 不论在jdk内部二进制是按照什么码存储的,在这两个方法中的二进制都是按照补码的方式来进行的。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.byfree.top/archives/binary