从0开始的C语言(八)浮点类型

📅 2026/6/17 1:06:32
从0开始的C语言(八)浮点类型
下面我们来看一下浮点数和浮点类型浮点数说白了就是小数 而浮点类型常用的有单精度浮点类型float 和 双精度浮点类型double尾数基数一共有多少个有效数字如3.14159的尾数基数就是6指数在浮点数存储之中确定小数点的位置用来存10的几次幂计算机储存浮点数也是以二进制去存储的浮点数IEEE754指数偏移存储原理首先我们可以通过sizeoffloat知道 单精度类型float的字节大小是4字节也就是32位而这32位当中符号位占1位 指数位占8位那么剩下的基数也就是尾数就占了23位 加在一起正好32位别问我为什么这样安排它就是这样儿那就有闲的没事的人要问了那这个8位的指数是怎么存的呢这里我们要声明一下C语言的存储方式都是二进制所以这个指数它肯定也是以二进制的方式进行存储的那么这个八位的指数它具体该怎么以二进制的形式去存储呢这就要设计到一个叫做IEEE754的标准这个标准就是定义 单精度float类型 那八位的指数 是怎么存储的首先要说一下符号位只有整个浮点数的开头才有并且仅此一个没有别的符号位了所以指数的那八位里面没有符号位全都是有效位因为有八位所以指数可以表示256个数从0 到 255 因为0000 0000 是0 1111 1111 是255而IEEE754给了一个特别巧妙的设计它们把正负数都存到了这256个数里面即不管浮点数的指数幂 是正的还是负的都可以用这个标准来表达那么是怎么用这个指数来表示正数和负数的呢它有一个很巧妙的设计因为有256个数从0 到 255 所以对255 / 2 去掉小数点得到 127于是就以这个127为标准 即把127看做是0然后往127的左边去的值叫做左偏移 往127右边去的值叫做右偏移此处可以看成往左边是递减往右边是递增例如127往左边偏移一位变成126这就意味着 127 - 1所以呢如果指数的这八位最后存储的是126的二进制数就意味着 该浮点数的指数是 10的-1次幂如果是往右边偏移的话例如指数的值是130 即指数的这八位存储的是130的二进制数那就意味着127往右边偏移了3位 即 127 3 就意味着 该浮点数的指数是 10的3次幂IEEE754就是用这个区间 来去判断 浮点数的10的次幂是正的还是负的例如314159 * 10的-5次方 存到内存的时候 首先这个数是正数所以符号位是0然后该数的基数尾数是314159 直接转换成二进制数存到基数的23位里最后看指数既然指数是 10 的-5次幂 所以计算机判断出来是 127往左边偏移了5位 即122然后再把122转换为二进制数最后存储到指数的 那八位的空间里代表是10 的-5次幂这个314159 * 10的-5次幂到此就存完了大于1的浮点数是规范化浮点数(比如2.5 5.14 9.527)小于1的是非规范化浮点数比如0.99 0.28 0.284下图的讲解就对应了我们上面说的IEEE754标准float类型占4字节即32位其中正负号占一位中间的占23位指数幂占八位但其实中间那23位还有一个隐藏的第24位隐式的位以防不备之时应对下溢underflow至于下溢是什么我们马上就会讲解浮点数的大小并不是由 基数尾数那23位 决定的而是由指数那8位决定的float是单精度double是双精度并且要注意给float类型的变量赋值时最好在赋的数值后面加上后缀f/F来标注出是float变量给变量名命名不要起abc这种的意义不明的名字要起的容易理解起的有意义或者就是在描述某种东西例如person_number , temperature speed_of_sound score , length , height 等等给变量命名有两种方法驼峰命名法和下划线命名法驼峰命名法 PersonNumber大驼峰命名法 personNumber小驼峰命名法下划线命名法person_number个人更喜欢用下划线命名法一点~Float变量用%f来格式化输出例子运行结果聪明的你可能注意到了输出的数据中有些丢失了精度下面我们就来解答这个问题吧float变量储存的数据可能会丢失精度原因是因为给float变量赋的值要转化成二进制储存在电脑里而浮点数小数点后面的小数部分在转换为二进制数时会发生一些误差可能会转换为无限不循环的二进制数你可以理解成有的小数点数转换为二进制数时除不开了所以变成了无限不循环二进制数所以会导致数值在小黑框中输出时会有一些数值上的误差在定义float类型变量时一定要加上后缀f/F来告知别人这是float类型提醒别人可能会发生丢失精度的问题小扩展在C语言的printf里想要输出%符号只需要打出两个%即可即“%%”就可以输出一个%了关于%E和%A例子运行结果%e和%E 以及 %a和%A只有小写和大写的区别除此之外都一样