double运算精度问题
题⽬:
下列表达式中,可以得到精确结果的是()
A.double d1 = 3.0 - 2.6;
B.double d4 = 2.5 * 1.5;
C.double d2 = 30/300;
D. double d3 = 1/2 + 0.5;
a因为double⽤⼆进制计算,因为0.6转换成⼆进制有精度损失,所以计算结果为0.3999999999999999
c 30/300都是整数计算起来是0 ⽽你付值给double 就变成了0.0
d1/2=0,然后+0.5就是0.5
0换算成⼆进制是⽆限循环⼩数后⾯是⽆穷⽆尽的,⽽double再长也得有个范围,后⾯的只能四舍五⼊,
导致了精度的缺失,⽽1.5和2.5就没有这个问题,1.5的⼆进制是1.1,2.5的⼆进制是11.1,所以不存在精度缺失的问题
就像⼗进制10除以3,是3.333333333⼀样的道理
使⽤Java,double 进⾏运算时,经常出现精度丢失的问题,总是在⼀个正确的结果左右偏0.0000**1。特别在实际项⽬中,通过⼀个公式校验该值是否⼤于0,如果⼤于0我们会做⼀件事情,⼩于0我们⼜处理其他事情。这样的情况通过double计算出来的结果去和0⽐较⼤⼩,尤其是有⼩数点的时候,经常会因为精度丢失⽽导致程序处理流程出错。
所以⼀般对double类型进⾏运算时,做好对结果进⾏处理,然后拿这个值去做其他事情。
/**
* 对double数据进⾏取精度.
* @param value double数据.
* @param scale 精度位数(保留的⼩数位数).
* @param roundingMode 精度取值⽅式.
* @return 精度计算后的数据.
*/
public static double round(double value, int scale,
int roundingMode) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(scale, roundingMode);
double d = bd.doubleValue();
bd = null;
return d;
}
/**
* double 相加
* @param d1
bigdecimal取值范围* @param d2
* @return
*/
public double sum(double d1,double d2){
BigDecimal bd1 = new String(d1));
BigDecimal bd2 = new String(d2));
return bd1.add(bd2).doubleValue();
}
/**
* double 相减
* @param d1
* @param d2
* @return
*/
public double sub(double d1,double d2){
BigDecimal bd1 = new String(d1));
BigDecimal bd1 = new String(d1));
BigDecimal bd2 = new String(d2));
return bd1.subtract(bd2).doubleValue();
}
/
**
* double 乘法
* @param d1
* @param d2
* @return
*/
public double mul(double d1,double d2){
BigDecimal bd1 = new String(d1));
BigDecimal bd2 = new String(d2));
return bd1.multiply(bd2).doubleValue();
}
/
**
* double 除法
* @param d1
* @param d2
* @param scale 四舍五⼊⼩数点位数
* @return
*/
public double div(double d1,double d2,int scale){
// 当然在此之前,你要判断分母是否为0,
// 为0你可以根据实际需求做相应的处理
BigDecimal bd1 = new String(d1));
BigDecimal bd2 = new String(d2));
return bd1.divide
(bd2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); }
这样,计算double类型的数据计算问题就可以处理了。
另外补充⼀下 JavaScript 四舍五⼊的⽅法:
⼩数点问题
function formatFloat(src, pos)
{
und(src*Math.pow(10, pos))/Math.pow(10, pos);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论