什么是二进制计数法?
为了让你更好地理解二进制计数法,我们先来简单地回顾一下人类计数的发展史。原始时代,人类用路边的小石子,来统计放牧归来的羊只数量,这表明我们很早就产生了计数的意识。后来,罗马人用手指作为计数的工具,并在羊皮上画出Ⅰ、Ⅱ、Ⅲ来代替手指的数量。表示一只手时,就写成“Ⅴ”形,表示两只手时,就画成“ⅤⅤ”形等等。公元 3 世纪左右,印度数学家(也有说法是阿拉伯人)发明了阿拉伯数字。阿拉伯数字由从 0 到 9 这样 10 个计数符号组成,并采取进位制法,高位在左,低位在右,从左往右书写。由于阿拉伯数字本身笔画简单,演算便利,因此它们逐渐在各国流行起来,成为世界通用的数字。日常生活中,我们广泛使用的十进制计数法,也是基于阿拉伯数字的。这也是十进制计数法的基础。因此,相对其他计数方法,十进制最容易被我们所理解。
让我们来观察一个数字:2871。
其中 ^ 表示幂或次方运算。十进制的数位(千位、百位、十位等)全部都是 10^n 的形式。需要特别注意的是,任何非 0 数字的 0 次方均为 1。在这个新的表示式里,10 被称为十进制计数法的基数,也是十进制中“十”的由来。这个我想你应该好理解,因为这和我们日常生活的习惯是统一的。
明白了十进制,我们再试着用类似的思路来理解二进制的定义。我以二进制数字 110101 为例,解释给你听。我们先来看,这里 110101 究竟代表了十进制中的数字几呢?
刚才我们说了,十进制计数是使用 10 作为基数,那么二进制就是使用 2 作为基数,类比过来,二进制的数位就是 2^n 的形式。如果需要将这个数字转化为人们易于理解的十进制,我们就可以这样来计算:
推荐丛书:<程序是怎样跑起来的> 二进制章节
按照这个思路,我们还可以推导出八进制(以 8 为基数)、十六进制(以 16 为基数)等等计数法,很简单,我在这里就不赘述了。至此,你应该已经理解了什么是二进制。但是仅有数学的理论知识是不够的,结合相关的代码实践,相信你会有更深刻的印象。基于此,我们来看看二进制和十进制数在 Java 语言中是如何互相转换的,并验证一下我们之前的推算。我这里使用的是 Java 语言来实现的,其他主流的编程语言实现方式都是类似的。
这段代码的实现采用了 Java 的 BigInteger 类及其 API 函数,我都加了代码注释,并且穿插一些解释,你应该可以看懂。首先,我们引入 BigInteger 包,通过它和 Integer 类的 API 函数进行二进制和十进制的互相转换。
import java.math.BigInteger;
public class Lesson1_1 {
/**
* @Description: 十进制转换成二进制
* @param decimalSource
* @return String
*/
public static String decimalToBinary(int decimalSource) {
BigInteger bi = new BigInteger(String.valueOf(decimalSource)); //转换成BigInteger类型,默认是十进制
return bi.toString(2); //参数2指定的是转化成二进制
}
/**
* @Description: 二进制转换成十进制
* @param binarySource
* @return int
*/
public static int binaryToDecimal(String binarySource) {
BigInteger bi = new BigInteger(binarySource, 2); //转换为BigInteger类型,参数2指定的是二进制
return Integer.parseInt(bi.toString()); //默认转换成十进制
}
public static void main(String[] args) {
int a = 53;
String b = "110101";
System.out.println(String.format("数字%d的二进制是%s", a, Lesson1_1.decimalToBinary(a))); //获取十进制数53的二进制数
System.out.println(String.format("数字%s的十进制是%d", b, Lesson1_1.binaryToDecimal(b))); //获取二进制数110101的十进制数
}
}