前提知识十进制小数表示二进制小数表示以此类推。。。浮点数float在计算机的存储IEEE 754 单精度浮点数32 位的结构符号位1 位表示正负。指数位8 位范围为 \(-126 \sim 127\)偏置值 127。尾数位23 位隐含最高位的 1实际表示 24 位有效数字\(2^{24}\) 种组合。示例例 4.25 这个浮点数先将其转换为二进制即 100.01然后再用二进制科学计算法表示,转换过程为100.01 - 1.0001 ^ 2 - 1.0001 ^ 10最终十进制4.25的二进制为 1.0001^10。那么其中的 1.0001 是尾数存放在尾数位10 二进制为 指数存放在指数位符号为0代表正数。存放在符号位整数位表示所以用这种表示方法计算机能从0开始连续精确表示的最大整数值就是1.111...111 小数部分23个1 ≈ 2 * 2^23 ≈ 2 * 2^23 2^24近似等于 将小数点向前移动了23位2^24 - 1 16777215,能精确表示的最大正整数 16777215此时小数位已经发挥到极限了要表示更大的数只能去增加指数位那么此时指数最大能够使小数点向前移动多少位呢哇这空间绰绰有余这时根据木桶原理比较之下发现尾数位的有效数字位数才是制约我们的条件让我们不能随意向后拓展。我能只能精确表示之间的整数。那么如果我们想表示16777217内存中该如何存储呢理论上应该让尾数变为int main() { float a 16777217; return 0; }此时实际的有效数字会默认在末尾多出一个零在我们增加有效数字的同时其实并不是在最末未位置增加的而是在倒数第二位增加的所以计算机存储是连续两个值都用的相同的存储方式。16777218 1.00000...000001 0 * 2^24int main() { float a 16777218; return 0; }int main() { float a 16777219; return 0; }16777220 1.00000...000010 0 * 2^24int main() { float a 16777220; return 0; }所以如果用float保存整数会有误差而且误差会根据具体要表示的整数值发生变化比如当 -16777216 val 16777216时是能精确表示的误差为0当val 16777216时误差为1当继续增加指数位到极限值时127这就是float能表示的最大值了2^(128-1)小数位表示二进制的十分位1表示0.5百分位1表示0.25千分位1表示0.125以此类推。所以说float也不一定能精确表示一个小数类似于搭积木我有很多小积木0.50.250.125...一共有23个尾数位数这23个积木的组合是无法表示无穷无尽的小数的只能有限接近。具体怎么搭这个积木这里不过多介绍只是给出个大致思路首先要明确两点1、同一个积木不能重复利用两次2、所有的积木相加的和约等于1我们拼凑完后的数字S与实际值的差应该小于最小积木的值。所以说用float表示小数也会存在误差不过这个误差需要根据具体值进行计算但始终小于最小积木的值。这也是用号比较浮点数变量和字面量会false的原因