浮点数的概念是相对于定点数来说的:
- 定点数:小数点的位置是固定的。(小数点的左边表示整数部分,小数点的右边表示小数部分)
- 浮点数:小数点的位置是浮动的。
假设目前只有8bit存储空间可供表示一个数,我们把第一位用于符号位,剩下7位用于数值位。那么一个数值用两种方式的表示规则如下。
定点数表示
假定将小数点放在第五个bit,那么前三位将用于表示整数部分,后四位则用于表示小数部分。
定点数表示举例:10000.000 == +1.0 ;00000.000 == -1.0;10011.000 == +3.0;00111.101 == -(7+5/8)
取值范围
整数部分的可表示的最大绝对值是:2^4 = 16,小数部分可表示的最大绝对值是:2(n-1)/2n = 1/2 + 1/4 + 1/8 = 7/8。
那么小数点在第5位的8bit定点数可以表示的数值范围是: -(16+7/8) ~ +(16+7/8)。
精确度
对于整数部分,只要在表示范围内,都是绝对精确的。上面的8个bit可以精确的表示-16 ~ +16的任何一个整数
对于小数部分,由于只有三个小数位,所以小数部分只能精确的表示1/2^3(即1/8)的倍数,能精确表示的小数是有限的(即只能精确的表示7个小数,1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8)。而小数是无限的,所以要先表示某个小数,只能近似的去表示它,如想表示3.15/8,那只能找最近的3/8去近似的表示它。
采用定点数,从数轴的角度来看,所表示的这些数的分布是均匀的(即两个相邻的数的差值总是一个定值,此处是1/8)
浮点数表示
浮点数的小数点位置是不固定的,一个浮点数的表示方法统一采用:符号+尾数+阶数(例如:+1.234 * 2^3 == 9.872)
因为尾数的第一位总是1,所以此处可以省出一位数。我们假定:对于8bit位浮点数,第一位为符号位,二三位为阶码位,四五六七八位为尾数位
那么有,阶码的取值范围是2^-2 ~ 2^2(1/4,4),尾数的取值范围是1 ~ 1+ 1/2 + 1/4 + 1/8 + 1/16 + 1/32(即1~1+(31/32))
所以,该浮点数能表示的最大的绝对值是(1~1+(31/32)*2^4
表示方法的最大精度为1/16,即小数点后两位(近似两位,其实连两位也不到,因为只能表示1/16的整倍数)
我们以float类型为例,float有22位尾数:1/2^22 = 0.00000024。所以float表示纯小数时能表示0.00000024的倍数的那些数,即也能表示5 * 0.00000024 = 0.0000012(约等于0.0000001)。所以float表示纯小数时近似精确到小数点后6位。当然,这是把尾数全部用于表示小数时能精确到后六位,当有一部分用于表示整数时(即当阶码的值大于0时),精确度就不能到达6位了,甚至当阶码比较大时(因为阶码决定了小数点的位置),连个位,十位,百位也不能精确表示了。
采用浮点数,从数轴的角度来看,越靠近0的地方,数越密集,越靠近两端数越稀疏,所以用浮点数表示一个数,该数的绝对值越小,误差越小,绝对值越大误差越大。