
如果将 0.1 累加 100 次,结果等于 10 吗?
#include <stdio.h>
int main() {
float sum;
int i;
// 将用来保存累加结果的变量清零
sum = 0;
// 将 0.1 累加 100 次
for (i = 1; i <= 100; i++) {
sum += 0.1;
}
// 显示结果
printf("%f\n", sum);
return 0;
}
在这里,他的结果等于 10.000002
为什么?来看二进制如何表示小数
举例:计算 1011.0011

前面知道 位权
图中4位二进制小数能表示的数值范围是 0.0000~0.1111
那么你给它一个十进制数 0.1,它如何表示?它无法通过 2 的负整数次幂相加来刚好凑出 0.1,最终会得到一个循环小数。上面的例子会得到 0.00011001100…(之后 1100 不断重复)
为什么?
目标:拿到 0.1 1/2 = 0.5 太大了,不取 1/4 = 0.25 太大了,不取 1/8 = 0.125 太大了,不取 1/16 = 0.0625 取! 剩余 0.1 - 0.0625 = 0.0375 1/32 = 0.03125 取! 剩余 0.0375 - 0.03125 = 0.00625 1/64 = 0.015625 太大了,不取 1/128 = 0.0078125 太大了,不取 1/256 = 0.00390625 取! 剩余 ...
为什么有些十进制小数用二进制表示时,会出问题?
因为一个小数能不能被二进制精确表示,关键看它化成分数以后,分母里是不是只剩下 2。
如何去判断能否被二进制精确表示? 以 0.375 举例
反过来,0.1 = 1/10,而 10 = 2 × 5。分母里除了 2 还有 5,所以它用二进制就表示不完。
接下来是浮点数
常见的有
浮点数你可以先理解成,它把一个数拆成符号、尾数、基数和指数这4个部分来表示

那么,如何去避免计算机计算出错呢?两种方法
#include <stdio.h>
int main() {
// int 是整数数据类型
int sum;
int i;
// 将用来保存累加结果的变量清零
sum = 0;
// 将 1 累加 100 次
for (i = 1; i <= 100; i++) {
sum += 1;
}
// 将结果除以 10
sum /= 10;
// 显示结果
printf("%d\n", sum);
return 0;
}
二进制与十六进制
二进制在计算机里很有用,因为它和底层电路的状态很接近,但缺点是位数太长,看起来费劲
那么 4 位二进制刚好等于 1 位十六进制数,例如
说到底,问题并不是计算机不会算,而是有些十进制小数本身就没法用有限位的二进制精确表示。
所以很多时候,误差不是算错了,而是存的时候就已经只能存一个接近值。
这也提醒我们,在看待浮点数的时候,不能把它当成数学里的实数,而要把它当成一种“有限精度的近似表示”。