千家信息网

Java Double相加出现的问题有哪些

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍"Java Double相加出现的问题有哪些",在日常操作中,相信很多人在Java Double相加出现的问题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对
千家信息网最后更新 2026年11月02日Java Double相加出现的问题有哪些

这篇文章主要介绍"Java Double相加出现的问题有哪些",在日常操作中,相信很多人在Java Double相加出现的问题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java Double相加出现的问题有哪些"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    Java Double相加出现的怪事

    问题的提出

    编译运行下面这个程序会看到什么

    public class test { public static void main(String args[]) {  System.out.println(0.05 + 0.01);  System.out.println(1.0 - 0.42);  System.out.println(4.015 * 100);  System.out.println(123.3 / 100); }};

    你没有看错!结果确实是

    0.060000000000000005
    0.5800000000000001
    401.49999999999994
    1.2329999999999999

    Java中的简单浮点数类型float和double不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上面的错误。现在终于理解为什么要有BCD码了。

    这个问题相当严重,如果你有9.999999999999元,你的计算机是不会认为你可以购买10元的商品的。

    在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。现在让我们看看如何解决这个问题。

    解决方案

    现在我们已经可以解决这个问题了,原则是使用BigDecimal并且一定要用String来够造。

    但是想像一下吧,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类Arith来简化操作。它提供以下静态方法,包括加减乘除和四舍五入:

    public static double add(double v1, double v2);  public static double sub(double v1, double v2);  public static double mul(double v1, double v2);  public static double div(double v1, double v2);  public static double div(double v1, double v2, int scale);  public static double round(double v, int scale);package org.nutz.mvc.core; import java.math.BigDecimal; public class Arith { // 源文件Arith.java:  /**  * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。  */  // 默认除法运算精度 private static final int DEF_DIV_SCALE = 10;  // 这个类不能实例化 private Arith() { }  /**  * 提供精确的加法运算。  *   * @param v1  *            被加数  * @param v2  *            加数  * @return 两个参数的和  */  public static double add(double v1, double v2) {  BigDecimal b1 = new BigDecimal(Double.toString(v1));  BigDecimal b2 = new BigDecimal(Double.toString(v2));  return b1.add(b2).doubleValue(); }  /**  * 提供精确的减法运算。  *   * @param v1  *            被减数  * @param v2  *            减数  * @return 两个参数的差  */  public static double sub(double v1, double v2) {  BigDecimal b1 = new BigDecimal(Double.toString(v1));  BigDecimal b2 = new BigDecimal(Double.toString(v2));  return b1.subtract(b2).doubleValue(); }  /**  * 提供精确的乘法运算。  *   * @param v1  *            被乘数  * @param v2  *            乘数  * @return 两个参数的积  */  public static double mul(double v1, double v2) {  BigDecimal b1 = new BigDecimal(Double.toString(v1));  BigDecimal b2 = new BigDecimal(Double.toString(v2));  return b1.multiply(b2).doubleValue(); }  /**  * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。  *   * @param v1  *            被除数  * @param v2  *            除数  * @return 两个参数的商  */  public static double div(double v1, double v2) {  return div(v1, v2, DEF_DIV_SCALE); }  /**  * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。  *   * @param v1  *            被除数  * @param v2  *            除数  * @param scale  *            表示表示需要精确到小数点以后几位。  * @return 两个参数的商  */  public static double div(double v1, double v2, int scale) {  if (scale < 0) {   throw new IllegalArgumentException(     "The   scale   must   be   a   positive   integer   or   zero");  }  BigDecimal b1 = new BigDecimal(Double.toString(v1));  BigDecimal b2 = new BigDecimal(Double.toString(v2));  return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); }  /**  * 提供精确的小数位四舍五入处理。  *   * @param v  *            需要四舍五入的数字  * @param scale  *            小数点后保留几位  * @return 四舍五入后的结果  */  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(); }};

    Double相加时出现的多位问题

    String test = "40.61 ,  18588.73,    29925.07,    7986.06,    18639.19,    25914.32,     32907.74,     34165.89,     9724.7,     52777.92"; String[] arr = test.split(","); double sum = 0; for(int i=0;i

    结果: 230670.22999999998

    查了查 没有深入的了解,大概是java 的double机制,关于精度的问题,若是不出现这种情况,保留小数点后两位就可以了。或者使用BigDecimal进行计算,另外《effective java》这本书里也提过,double和float 不建议使用商业计算。

    补充:原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。

    我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。

    如:2.4的二进制表示并非就是精确的2.4。

    反而最为接近的二进制表示是 2.3999999999999999。浮点数的值实际上是由一个特定的数学公式计算得到的。

    到此,关于"Java Double相加出现的问题有哪些"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

    问题 精确 运算 点数 四舍五入 两个 参数 四舍 小数 情况 结果 二进制 小数点 方法 学习 数字 类型 精度 除法 加减乘除 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳九邦互联网科技有限公司 广州互联网科技公司 互联网与未来科技 广州互联网络科技有限公司 苏州互联网科技贷款公司 丰台科技园 互联网 天扬科技互联网广告 中国最先进互联网科技公司 互联网科技公司的市场部门 湖南洣水互联网科技有限公司扣款 深圳市优智互联网科技有限公司 中国互联网十大科技股排名 济南有互联网科技公司吗 怎样加入科技互联网 浙南科技城互联网大厦招聘 萌小萌互联网科技河南有限公司 全球科技与互联网公司市值变化 版纳互联网科技选哪家 北京天晋互联网科技有限公司 互联网 科技节活动 微视频大赛 科技和互联网公司 A股互联网金融科技公司 哈尔滨新华互联网科技学院 小米互联网科技园设置 武汉健翔互联网络科技有限公司 玉溪互联网科技怎么选 黑科技 体验场景 互联网大会 35岁以上互联网科技行业 众联互联网络科技 互联网科技创业有什么好项目
    0