我们知道编程语言中数字类型有整型和浮点型两种,当然不只是编程语言,我们常用的数据库中也是这样,它们能够容纳的数据范围,和他本身的数据长度到底有什么关系,这一点很多人都不太清楚。
在了解他们的关系之前,要知道两个知识点。第一个是二进制补码表示法
,这种表示法有利于计算机更快速的计算数据,少沉余的编码,具体指的是,数字的最大位用来表示符号,0为正号,1为负号,其他位表示数字本身。第二个是我这里所说的位数,并不是我们肉眼直接看见的个十百千万这种有一个算一位的位数,而是比特位数,在计算机底层的运行逻辑中,一个字节也就是用来表示文件大小的那个B
,当然我们日常见到的文件,通常是KB为单位。但B
并不是最小的存储单位,最小的存储单位就是现在要说的b
,叫做比特位数,我们通常直接叫做字位,一个字节B等于八个字位b。
当你知道上面说的两个东西,那么你就可以理解整形的数据范围,也就是当你规定数据长度为4,既长度为4字节时,整型数据所能容纳的数据范围是在 8 * 4 = 32 位之内,当你存储有符号数据时,由于最左侧的最大位数属于符号位所能容纳的数据也就只有31位了,就是说此时数据范围为-2∧(32-1) 到2∧(32-1)-1,即-2,147,483,648到2,147,483,647。对于无符号的int类型,它能够容纳的数据范围是从0到2^(32)-1,即0到4,294,967,295。
这个要解释一下,为什么存储有符号数据时,两侧的幂都要减一,左侧因为需要强制带符号,导致它的位数减去了一,而右侧是为了平衡与左侧的范围,所以在计算机内部规定右侧同样减一。
对于浮点数来说,浮点数类型通常有两种:float和double。其中,float类型是32位的单精度浮点数,double类型是64位的双精度浮点数,这也就是为什么直接进行浮点数换算时数据极其容易丢失精度,因为每个浮点数小数点后往往不是你原本数据的长度。
根据规范,浮点数的表示采用科学计数法,由三个部分组成:符号位、指数部分和尾数部分。
对于float类型,其中1位表示符号位,8位表示指数部分,23位表示尾数部分。根据规范,float类型能够表示的最大正数是1.8 x 10∧38,最小的正数是1.4 x 10∧-45。
对于double类型,其中1位表示符号位,11位表示指数部分,52位表示尾数部分。根据规范,double类型能够表示的最大正数是1.7 x 10∧308,最小的正数是4.9 x 10∧-324。
在最后我要说明一点,用于精度要求较高的浮点数类型,他们的数据范围,需要根据实际情况来定,不同的开发工具情况不同,不参与像上面说到的次幂计算。
就以Java中的BigDecimal来说,由于他在定义的时候就不需要指定长度,因此它的范围在理论上是无限的,再用它做计算的时候,只要你的设备性能吃得住,他的范围就可以一直扩大。而对应的,MySQL中的Decimal,你定义的长度就是它的数据位数,因此,默认情况下,MySQL的Decimal可以存储的数据范围是从-9999999999 到 9999999999,共10位。总结来说,用于高精度浮点数计算的类型,他能够容纳多大的数据取决于,你用的开发手段是什么。