解决double转 BigDecimal 时出现的精度失真问题

解决double转 BigDecimal 时出现的精度失真问题解决double转BigDecimal时出现的精度问题比如,doubledd=344999.03d;转成BigDecimal类型,BigDecimalss=newBigDecimal(dd);最后,ss的值是344999.03000000002793967723846435546875失真了。解决方法是先将dd转换字符串,然后转换成BigDecimal。/…

大家好,又见面了,我是你们的朋友全栈君。

比如,double dd=344999.03d;
转成 BigDecimal 类型,BigDecimal ss=new BigDecimal(dd);
打印 ss 的值是344999.03000000002793967723846435546875
精度失真啦!

解决方法是
先将 double 转换 字符串,
然后转换成 BigDecimal 。

代码:

/** * 解决double转bigdecimal时出现的精度问题 * @param v1 * @return */
public static BigDecimal doubleToBig(double v1) { 
   
	return new BigDecimal(String.valueOf(v1));
}

查询BigDecimal 源码,得出结论:
所有的 基本数字类型(float、double)转换 BigDecimal 或 BigInteger时,

先将 数字类型 先转成字符串,然后再转换BigDecimal 或 BigInteger。

最后,附上 double转 BigDecimal 的工具类

package com.delongra.nback.system.util;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/** * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。 */
public class DoubleUtil { 

// 默认除法运算精度
private static final int DEF_DIV_SCALE = 10;
/**#.## */
public static final String REG_1 = "#.##";
/** #,###.## */
public static final String REG_2 = "#,###.##";
// 这个类不能实例化
private DoubleUtil() { 

}
/** * 解决double转bigdecimal时出现的精度问题 * @param v1 * @return */
public static BigDecimal doubleToBig(double v1) { 

return new BigDecimal(String.valueOf(v1));
}
/** * 科学记数法转换成字符串 */
public static String doubleToStr(double v1) { 

BigDecimal b1 = new BigDecimal(Double.toString(v1));
return b1.toPlainString();
}
/** * 科学记数法转换成字符串 */
public static String stringToStr(String v1) { 

BigDecimal b1 = new BigDecimal(v1);
return b1.toPlainString();
}
/** * 主要用于格式化金额 * @param v1 * @return */
public static String format(double v1) { 

NumberFormat numberFormat = new DecimalFormat(REG_2);
String str = numberFormat.format(v1);
return str;
}
/** * 主要用于格式化小数点 * @param v1 * @param reg * @return */
public static String format(double v1,String reg) { 

NumberFormat numberFormat = new DecimalFormat(reg);
String str = numberFormat.format(v1);
return str;
}
/** * 加法 */
public static double add(double v1, double ...v2) { 

BigDecimal b1 = new BigDecimal(Double.toString(v1));
for (double vv : v2){ 

BigDecimal b2 = new BigDecimal(Double.toString(vv));
b1=b1.add(b2);
}
return b1.doubleValue();
}
/** * 减法 */
public static double sub(double v1, double ...v2) { 

BigDecimal b1 = new BigDecimal(Double.toString(v1));
for (double vv : v2){ 

BigDecimal b2 = new BigDecimal(Double.toString(vv));
b1=b1.subtract(b2);
}
return b1.doubleValue();
}
/** * 乘法 */
public static double mul(double v1,double ...v2) { 

BigDecimal b1=new BigDecimal(Double.toString(v1));
for (double vv : v2){ 

BigDecimal b2 = new BigDecimal(Double.toString(vv));
b1=b1.multiply(b2);
}
return b1.doubleValue();
}
/** * 除法 */
public static double div(double v1, double ...v2) { 

BigDecimal b1 = new BigDecimal(Double.toString(v1));
for (double vv : v2){ 

BigDecimal b2 = new BigDecimal(Double.toString(vv));
b1=b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
}
return b1.doubleValue();
}
/** * 小数的四舍五入 */
public static double round(double v, int scale) { 

if (scale < 0) { 

throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/** * 两个数比较,获取比较值相对于基准值的大小百分比 * @param base 基准值 * @param compare 比较值 * @return */
public static String getComparePercent(int base,int compare){ 

if (base==compare) { 

return "0%";
}
if (compare==0) { 

return "0%";
}
if (base==0) { 

return compare*100+"%";
}
NumberFormat numberFormat = NumberFormat.getInstance();  
numberFormat.setMaximumFractionDigits(2); // 设置精确到小数点后2位 
int margin = compare-base;
String result = numberFormat.format((float) margin / (float) base * 100);  
return result + "%";
}	
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/137391.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • abstract修改方法

    abstract修改方法

    2021年12月31日
  • CAP理论应用

    CAP理论应用神一样的CAP理论被应用在何方对于开发或设计分布式系统的架构师工程师来说,CAP是必须要掌握的理论。(but:这个文章的重点并不是讨论CAP理论和细节,重点是说说CAP在微服务中的开发怎么起到一个指引作用,会通过几个微服务开发的例子说说明,尽量的去贴近开发)CAP定理又被成为布鲁尔定理,是加州大学计算机科学家埃里克·布鲁尔提出来的猜想,后来被证明成为分布式计算领域公认的定理。不过布…

  • ireport教程_linear predictor

    ireport教程_linear predictor三元元算($F{username}.equals(“a”))?”它是a”:”它不是a”

  • 雅虎优化ETags

    雅虎优化ETagsETags为网页资源的优化又提供了一个便捷的方案。ConfigureETagstag:serverEntitytags(ETags)areamechanismthatwebserversandbrowsersusetodeterminewhetherthecomponentinthebrowser'scachematchest

  • arcmap重采样_ipproto_raw

    arcmap重采样_ipproto_raw参考文献:AcceleratedHypothesisGenerationforMulti-structureRobustFitting假设Input:{xi}i=1N\{x_i\}_{i=1}^N{xi​}i=1N​代表输入的N组数据,由N组数据随机采样生成了M个模型θ1,θ2,…θM{\theta_1,\theta_2,…\theta_M}θ1​,θ2​,…θM​,对于每一个个输入数据xix_ixi​,我们计算模型的残差得到该模型的分数r(i)=[r1(i),r2(i)…rM

  • 如何使用pc3000改变西数硬盘的模块位置

    如何使用pc3000改变西数硬盘的模块位置

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号