最近做练习的时候发现了一个有意思的问题,具体如图:
按理说这段代码的输出应该为 28.26,但实际上
分析
于是我上网查了查,大概的解释就是 二进制有时无法准确的表示小数位
大家应该都知道,计算机底层是用二进制来存储数据的,而学过 计算机组成原理 的同学也应该都了解一些 十进制小数 转二进制的弊端,即
某些小数转化为二进制后的位数可能会很大或者是无穷尽的
而float与double类型变量能存储的二进制位数是有限的,多余的位数会被截断,这就造成了数据精度的丢失,这种精度的丢失在浮点数相乘的情况下会显得尤为明显
但是,十进制整数 在转二进制时就不会出现位数无尽的情况
解决
要想解决这一问题,有两种方法
一、先把浮点数的小数位去除,计算结束后再归还小数位,即
这是结果
二、使用java.math包里的 API BigDecimal ,具体的使用方法请移步这篇文章 Java之BigDecimal详解
double pi = 3.14, r = 3;
String pistr = String.valueOf(pi);
String rstr = Double.toString(r);
BigDecimal rbd = new BigDecimal(rstr);
BigDecimal area = new BigDecimal( pistr ).multiply( rbd ).multiply( rbd );
System.out.println( area.doubleValue() );
结果同上
需要注意的是, 调用BigDecimal的构造函数时,传入的参数最好为 String 类型的变量,即
new BigDecimal(String str)
int、double类型变量与String类型的转换可参考我之前的文章 java 实现 int、double类型 与 String 类型 相互转换