1. C语言的double类型的精度(有效位数)是16位。
表示的数字通常是这样 :
X.XXXXXXXXXXXXXXXX E
XX,底数X.XXXXXXXXXXXXXXXX有17位数字,也就是说小数点后有16位,最后一位通常是不保证准确的。
二进制的数字,如果有小数部分,那么化成十进制,最后一位小数一定是5.
自然界中的小数,往往不能被二进制的计算机精准表示。但是,double类型可以保证,计算机内存中的数字的16位有效数字是和自然界的数字一样的。后面的有效数字便不能保证了。
比如:1.000000000000001,有15位小数,16位有效数字,它是一个自然界的数字。计算机中他表示为:2^0 +
2^(-50)+2^(-52) = 1.0000000000000011022302XXXXXXXX5,最后一位一定是5.
这就是double能准确表达自然界中数字的精度问题。
2. 1/2^k
转化成十进制,小数点后有k位数字(但并非都是有效数字)。因为小数点后面会先跟一些零,每个十进制的零对应二进制3到4bit的0.
3. 1/2^24
= 5.9604644775390625e-008
可以看到底数部分有17位有效数字,16位小数部分。指数部分有8位小数点移动。也就是说这个数字小数点后有24位,与2的结论吻合。同时这个数字是17位有效数字的double能表示的最小的定点数(注意是定点数)。
在vs2005中,1/2^25 =
2.9802322387695313e-008。很明显,1/2^25有18位有效数字,超过了double的精度,并不是超了表示范围,而是精度不够表示。
但在计算机内存中,这个数字还是被完全精度的存放的。调试界面只会出现17位有效数字。也就是说,定点仿真,double可以搞定任何小于等于52bit的定点数。到这里,定点数和浮点数的区别,无非是浮点数按照IEEE的格式,有一些字段专门记录小数点的位置的偏移,而定点数的小数点是定死的,需要程序员维护,而不是在数据类型中维护。