C++ float double 精度
转自:https://blog.csdn.net/black_kyatu/article/details/79257346
float、double数据类型的表示范围及精度问题
c++ pp Page49
要弄清楚这个问题,首先要搞清楚浮点数在内存中的存储方式。浮点数,区别于定点数,指的是小数点位不确定的的数据类型,其原理是将一个浮点数a用两个数m(尾数)和e(指数)来表示:a = m × b^e。其中的b为选取的基数。科学计数法就是一种特殊形式的浮点数。
在计算机二进制表示中,浮点数采用2作为基数,规定尾数的范围为1.0~2.0之间。
以float类型为例,根据最广泛采用的IEEE754标准规定,float数据类型长度为32位,其中最高位为符号位,中间8位为指数位,最后23位作为尾数位。
最高位符号位通过0/1来区分正负,0正1负;指数位则规定采用移码的形式存储,这样可以保证指数部分为无符号数,方便比较大小。移码表示法是在数X上增加一个偏移量来定义的,如果机器字长为n,规定偏移量为2^(n-1),对于8位补码-128~127,可得到对应的阶码表示为0~255,其中全0和全1分别用来表示0和无穷大,故规定1~254用来表示规范数字,即对应指数范围从-126到127;尾数部分统一规定为1.0-2.0之间,最高位必然为1,故可以省略,所以尾数部分从小数点后算起,最小可以取到1,最大则取到二进制1.1...1(小数点后23位),即取到2-2^-23,可近似约等于2。故得到float绝对值的最大值取到2^127*(2-2^-23)约等于2^128=3.4E+38。加上符号之后可得float表示范围为(-3.4E+38)~(3.4E+38)。当然实际是取不到的,开区间。绝对值最小则可以取到2^-127*1,即为1.175E-38。
接下来解释精度。由于尾数部分位数是固定的小数点后23位,23位所能表示的最大数是2^23−1=8388607,所以十进制的尾数部分最大数值是8388607,也就是说尾数数值超过这个值之后,float将无法精确表示,所以float最多能表示小于8388607的小数点后7位,但绝对能保证的为6位,也即float的十进制的精度为为6~7位。
double数据类型的推算过程和上述同理,唯一的区别在于尾数由23位扩展到52位,阶码由8位增加到了11位,计算方法不变。所以double的阶码(移码表示)为1~2046,偏移量为1023,故指数范围为-1022~1023,得表示范围为(2^1023*2)~(-2^1023*2)即为-1.7E+308~1.7E+308,绝对值最小可以取到2^-1022,精度则为2^52-1=4503599627370495,为16位。所以精度最高位16位,一定可以保证15位。
-----------------------------------2023/1/4----------------------------
参考
https://blog.csdn.net/K346K346/article/details/50487127
这篇文章的第六部分,讲解的很详细,关于这篇文章中“有效数字”的概念,百度:“从第一个不是零的数字开始往后数,有几位数字就是几位有效数字。”