《这些年编程的一些反思》003. 整型和浮点型

和我们小学时候学习数学一样,问题先从123这样的整数学起,然后再慢慢的学分数,学小数。在计算机中也是这样,虽然这些数都是数学上的实数,但是,在计算机中,表示的方法却是大不一样。除了数学,还有语文,对语文来说,语言文字是重要的组成部分,所以,在计算机中,如何表达这些字符也是非常重要的一个方面。因此,数学上的数字,语文上的文字,在现实中是不同的科目,在计算机中是不同的类型。虽然在计算机中,最底层的表示都是数字0和数字1,但是,必须要人为的定义一种约定,让这些用0和1来表示的数字串有不同的意义。

中国有句古话:“橘生淮南则为橘,生于淮北则为枳。” 就有点这个意思,同样的一串数字,如果认为是整数则表示某种意义,如果认为是字符串则是另外一个意义。如果你是一个有名气的富人,如果在公共场合穿拖鞋,就是接地气,平易近人,如果你是个穷鬼,在公共场合穿拖鞋,就是个没素质的家伙。是的,同样是公共场合穿拖鞋这件事,因为不同的身分,就会被解读出不同的意义。

计算机中的事情,总是能够找到现实中不同的解读。下面,我就来解读一下各种数据类型。

整数类型

我们总是从123开始学习的数学,这个123就是整数类型。我记得小学时候的作业经常是回家写123456789,然后每个数字写10遍。如果给你一张田字格纸,每个格子里只能写一个数,你能写的最大的数是多少呢?顶多就是写满9,不能再大了,如果是在田字格纸上写数字,写满了还可以换一张纸继续写,但是,在计算机中就没有这么好的运气了。如果写满了,就会有个经典的错误叫:溢出。是的,就是精满则溢的溢,中出的出。溢出的根本原因是田字格不够用了。

在编程语言中,人为规定了整数能够使用的田字格的长度,这个世界就是这样,经常出现各式各样的人为定义。比如在C语言中,表示正整数的只能使用8个田字格的类型叫无符号的8-bit整数,可以表示0到255之间的任何一个数。如果可以表示正整数又可以表示负整数的,也是只能使用8个田字格的类型,有个名字叫带符号的8-bit整数,这个数可以表示-128到127之间的任何整数。我测试了一下苹果新推出的Swift语言,里面的Int类型,最大和最小的值分别是下图:

是的,非常非常巨大的一个数字,如果我能有这么多钱就好了,即使单位是日元也挺好的。

浮点类型

浮点,英文名叫Floating-Point,为什么叫浮点呢,而不是叫凸点呢?有没有想过这个哲学问题呢?那是因为浮点真的会浮,而不会凸,会凸的是下面这种东西。

我来讲讲为什么浮点会浮吧。在整数类型中,我已经讲了整数如何表达,其实,整数是相对比较容易表示的,反而是3.1415这种的,难以在计算机中表示。怎么记录下这个小数点呢?起初,人为的规定(是的,人就是这样,经常搞人为规定)小数点的位置,比如说,人为规定,看见整数就左移4位,比如,31415,左移4位就成了3.1415,1000左移4位就成了0.1,1左移4位就成了0.0001… 非常的简单粗暴,某些情况也有些效果。但是,如果领导要求小数点后4位不够精确了,要后5位怎么办呢?好办,再重新约定一个… 如果某天要求后10位了,这个应该怎么办?还是约定… 这种一碰到事情就开会约定的办法叫定点数。不叫浮点,浮点的小数点是可以浮动的。

我们再设计一个方法,一行田字格有16个格子。我们再人为规定一下,前10个格子是表示数的,后6个格子来表示小数点的位置。如果用10个格子中都填满1,这就是著名的1024-1=1023了。后面的6个格子里都填满1,因为小数点可以左右移动,因此可以移动左边-33,右移30。。因此,最大的数字可以表示为1023,后面跟30个0,这是一个超级巨大的数,如果表示很小的数,就是小数点后33位,这是一个超级小的数。一般情况下(或者任何情况下,光速的光速倍…这个数字大到天长久了已经…)我们用不到这么大的数字,也用不到这么小的数字。这基本上是浮点数的基本原理,当然,现实中有不同的实现方法,这些方法都已经写进IEEE 754 (IEEE Standard for Floating-Point Arithmetic) 中了,如果你特别喜欢仔细研究,可以下载看看,这个文档是绝对免费的纯沙漠级别的干货,里面有5种类型的标准,我只说了其中的一点点点点湿货。

需要注意的是,如果有同学是研究核弹,在银行工作的,在华尔街工作的,一定要特别注意,浮点数是不准的,几乎所有的语言都没有办法精确的实现1/3,1/5,1/7这种数,如果你是这种要求变态级别精确度的工作,应该有其它的方法,我就不作介绍了。最后,我来展示几个不准吧,比如10个0.3相加,或者11个0.3相加,几乎没有编程语言能算出是3,或者3.3来。

上图是使用苹果推出的swift语言,用11个0.3相加,得到的是3.2999999999。下图是Python 3.5, 用10个0.3相加,得到的是2.99999999996

那还能用浮点类型么?当然了,用魅族的老大黄章说的那句名言“天线性能差?又不是不能用!”来结束这一小节吧!

刘延栋 wechat
欢迎扫一下关注我的公众号:软件那些事儿
欢迎收听我的电台,你的支持将鼓励我继续前进