1前言我们在学习C语言的时候,通常认为浮点数和小数是等价的,并没有严格的区分。这并不影响我们的学习,因为浮点数和小数小数是绑定在一起的,只有小数是使用浮点数格式存储的。其实整数和小数都可以用定点格式存储,或者都可以用浮点格式存储,但实际情况是C语言用定点格式存储整数,而用浮点格式存储小数。”和“数值精度”是在这两个重要指标之间追求平衡的结果。2什么是浮点数?浮点型简单来说就是实数。浮点数在计算机中用来近似任何实数。具体来说,这个实数是用一个整数或定点数(即尾数)乘以某个基数(计算机中通常为2)的整数次方得到的。这种表示方法类似于科学记数法,abaseof10.3浮点数在内存中的存储首先要明确的是,整数、浮点数、字符等数据类型在计算机底层都是以二进制形式存储的。浮点数在内存中的存储不同于整数,因为整数可以转换成一一对应的二进制数据,浮点数的存储由符号位(sign)+指数位(exponent)组成+分数位(分数)。类型符号位指数尾数Float1位(第31位)8位(23~30位)23位(0~22位)Double1位(第63位)11位(52~62位)52位(52~62位)0~51bits)int和float也占用四个字节的内存,但是float可以表示的最大值比int大很多。根本原因是浮点数在内存中是以索引的形式存储的。将浮点数转换为内存存储的步骤分为以下三步:将浮点数转换为二进制,用科学计数法表示二进制浮点数计算指数的偏移值对于第三点:计算指数时需要加上偏移量(后面会介绍使用偏移量的原因),偏移量的值与浮点数的类型有关(float的偏移量值为127,偏移量double的值为1023)。例如,对于指数6,float和double的偏移值分别为:float:127+6=133double:1023+6=10294如何在float中存储示例浮点数19.625:转换浮点数转二进制:10011.101(19.625的整数部分除以2四舍五入,小数部分乘以2);用科学计数法表示二进制浮点数:1.0011101*2^4;计算指数偏移后的值:127+4=131(10000011);拼接综上所述,float类型的19.625在内存中的取值为:0-10000011-00111010000000000000000。5float和double的取值范围和精度取值范围由指数中的位数来决定。(因为表达式是1.x*2^Y的形式,所以忽略1.x的作用,直接取指数表示浮点数的范围)float:1bit(signbit)8bits(指数位)23bits(尾数位)double:1bit(符号位)11bits(指数位)52bits(尾数位)因此,float的指数范围为-127~+128,double的指数范围为-1023~+1024,和补码的指数以码的形式分开。其中,负数索引确定了浮点数所能表达的绝对值最小的非零数;正索引决定了浮点数所能表达的绝对值最大的数,即决定了浮点数的取值范围。float的范围是-2^128~+2^128,即-3.40E+38~+3.40E+38;double的范围是-2^1024~+2^1024,即-1.79E+308~+1.79E+308。精度float和double的精度由尾数中的位数决定。尾数越多,小数点后的有效位数越多,因此精度越高。浮点数在内存中以科学记数法存储,整数部分总是隐含的“1”。由于它没有变化,因此不会影响准确性。float:2^23=8388608,一共七位,也就是说最多可以有7位有效数字,但是绝对保证是6位,即float的精度是6~7位有效数字;double:2^52=4503599627370496,共16位,同理double的精度为15~16位。6解剖:为什么要用偏移法计算指数?如果不使用偏移法:8位二进制数表示的有符号数范围有两个区间:00000000~01111111和10000000~11111111,分别为0~+127和-127~0。这里大家看到问题了,有两个0,一个正0,一个负0。如果用偏移的方法:127转换成二进制:01111111,那么当我们要表示-127的时候,就有127-127,即01111111-01111111=00000000当我们要表示-126时,有127-126即01111111-01111110=00000001当我们要表示-2时,有127-2,即即,01111111-00000010=01111101当我们要表示-1时,有127-1,即01111111-00000001=01111110当我们要表示0时,有0+127,即,00000000+01111111=01111111。当我们要表示1时,我们有1+127,即00000001+01111111=10000000。当我们要表示2时,我们有1+127就是00000010+01111111=10000001当我们要表示128时,那么128+127就是10000000+01111111=11111111从上面的例子我们可以得出规律,利用移位存储技术,我们可以用8位二进制来共代表127个负数nu从-127到+128的数字+零(0)+128个正数,共256个数字。使用移位存储时+0和-0似乎没有问题,完全可以用新生成的8位二进制数来表示单精度浮点数的指数是非常合理的最大程度。本文转载自微信公众号《C语言与CPP编程》,可通过以下二维码关注。转载本文请联系C语言和CPP编程公众号。
