引言
很多人可能对发现这么一个问题,可能是在自学阶段、也可能是面试题上。
出现这种情况,首先最关注的点就在于浮点数的计算。
double精度
0.1*3属于double型的计算,
float的指数位有8位,而double的指数位有11位,
float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;
double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。
上面这么说,可能会感觉很奇怪,说精度和我现在讨论的这个话题有什么关系。
怎么说呢 如果我们使用的是float就不会出现这种问题,因为浮点数的机制中,精确值与精度有关。
浮点数的算法机制
对于0.1来说,其本质是 1 / 10,那么若你用二进制表示它们,然后除的话,是这样的:1 / 1010,然而这一个是除不尽的,是无穷循环。
===> 0.0 00110011001100110011001100110011… 其中0011循环
可以参考下面的博文https://blog.csdn.net/weixin_44018338/article/details/91420963
这样的机制就让我们的除法不能除尽,所以就出现了无限接近0.1的现象。而恰恰是double类的精度恰恰可以表现出0.30000000000000004,所以这就造成了double中的运算不准确的情况。
解决办法
针对这种问题,只能考虑使用小精度类型的float可以实现
System.out.println(0.1f*3);
这样输出的结果就会使0.3了