C语言浮点数的底层原理和精度损失问题
我们在平时的编程工作中,会经常接触到**“ 浮点数精度丢失 ”**问题。
一般的业务系统,“浮点数精度丢失”问题所导致的后果可能在业务可接受的范围,所以并没有起很多程序员的重视;
但是对于健壮性要求较强(比如,金融或财务系统),精度丢失所引起的后果就会是灾难性的,程序员离跑路已经不远了~~。
通过本文知识,让我们花5分钟时间彻底搞懂它,相信聪明的你,看完一定会有收获!
从一个经典例子谈起:
java语言示例:
public static void main(String[] args) {
double d1 = 0.1;
double d2 = 0.2;
System.out.println(d1+d2); //您认为结果是0.3? 真实结果是: 0.30000000000000004
}
上述两个算数的和,为什么不是0.3呢?就是因为“浮点数精度丢失”问题造成的。
“浮点数精度丢失”问题产生的原因
根本原因:
0.1这个十进制小数并不能很好的被二进制表示.
为什么0.1不能被二进制表示呢?
十进制小数转二进制的算法是:
- 整数部分:除 2 取余,直到商数为 0,结果逆序排列;
- 小数部分:乘 2 取整,直到小数部分乘积积为 0,结果顺序排列;
以0.125为例演示如下:
0.125 × 2 = 0.25 .......................0
0.25 × 2 = 0.5 .......................0
0.5 × 2 = 1.0 .......................1
即 十进制的0.125,表示成二进制为 0.001
现在来看十进制的0.1 转二进制:
0.1 × 2 = 0.2 .....................0
0.2 × 2 = 0.4 .....................0
0.4 × 2 = 0.8 .....................0
0.8 × 2 = 1.6......................1
0.6 × 2 = 1.2......................1
0.2 × 2 = 0.4......................0
........
这个算法过程是无限循环的,因此可以得出结论:浮点数的小数部分会有精度丢失问题