问题一

原理:在使用double计算时,经常会存在精度丢失,总是在一个正确的结果左右偏0.0000**1,经常会因为精度丢失而导致程序处理流程出错。所有在进行财务相关计算时,需要使用BigDecimal数据格式。

BigDecimal

在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。BigDecimal一共有4个够造方法,我们不关心用BigInteger来够造的那两个,那么还有两个, 它们是:

BigDecimal(double val) Translates a double into a BigDecimal.BigDecimal(String val) Translates the String repre sentation of a BigDecimal into a BigDecimal.

上面的API简要描述相当的明确,而且通常情况下,上面的那一个使用起来要方便一些。我们可能想都不想就用上了,会有什么问题呢?原来我们如果需要精确计算,非要用String来够造BigDecimal不可!在《Effective Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,这也许是一个小小的失误吧。

解决方案

现在我们已经可以解决这个问题了,原则是使用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)

所以一般对double类型进行运算时,做好对结果进行处理,然后拿这个值去做其他事情。

由于转换成为BigDecimal时不能使用new BigDecimal否则会造成资源浪费。应该使用:

BigDecimal bd = BigDecimal.valueOf(d1);
     /**   * 对double数据进行取精度.   * @param value  double数据.   * @param scale  精度位数(保留的小数位数).   * @param roundingMode  精度取值方式.   * @return 精度计算后的数据.   */   public static double round(double value, int scale,  int roundingMode) {    BigDecimal bd = BigDecimal.valueOf(value);  bd = bd.setScale(scale, roundingMode);    double d = bd.doubleValue();    bd = null;    return d;    }    /** * double 相加 * @param d1 * @param d2 * @return */ public double sum(double d1,double d2){ BigDecimal bd1 = BigDecimal.valueOf(d1);  BigDecimal bd2 = BigDecimal.valueOf(d2);  return bd1.add(bd2).doubleValue(); } /** * double 相减 * @param d1 * @param d2 * @return */ public double sub(double d1,double d2){ BigDecimal bd1 = BigDecimal.valueOf(d1);  BigDecimal bd2 = BigDecimal.valueOf(d2);  return bd1.subtract(bd2).doubleValue(); } /** * double 乘法 * @param d1 * @param d2 * @return */ public double mul(double d1,double d2){ BigDecimal bd1 = BigDecimal.valueOf(d1);  BigDecimal bd2 = BigDecimal.valueOf(d2);  return bd1.multiply(bd2).doubleValue(); } /** * double 除法 * @param d1 * @param d2 * @param scale 四舍五入 小数点位数 * @return */ public double div(double d1,double d2,int scale){ BigDecimal bd1 = BigDecimal.valueOf(d1);  BigDecimal bd2 = BigDecimal.valueOf(d2);  return bd1.divide  (bd2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } 

注释:

1:

scale指的是你小数点后的位数。比如123.456则score就是3.
score()就是BigDecimal类中的方法啊。
比如:BigDecimal b = new BigDecimal("123.456");

b.scale(),返回的就是3.

2:
roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。
3:

pubilc BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!

4:对于一般add、subtract、multiply方法的小数位格式化如下:

BigDecimal mData = new BigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("mData=" + mData);

----结果:----- mData=9.66

问题二

java中由于double计算时遇到数字过大或者过下,数字则会采用科学计数法,如果使用String.valueOf的话,会出现“1.0E-4”字符串。对后续运算造成障碍

采用下面代码可以解决问题,取消科学计数法

import java.text.NumberFormat;public class test {public static void main(String[] args) {double d =12345.00000000225168d;String s=formatDouble(d);System.out.println(s);}private static String formatDouble(double d) {NumberFormat nf = NumberFormat.getInstance();//设置保留多少位小数nf.setMaximumFractionDigits(20);// 取消科学计数法nf.setGroupingUsed(false);//返回结果return nf.format(d);}
}

java double丢失精度问题,加减乘除计算出错出现99999相关推荐

  1. java double 的精度_java double类型相加精度问题的解决

    我就废话不多说了,大家还是直接看代码吧~ package com.hxyl.action; import java.text.DecimalFormat; public class Test { pu ...

  2. float计算丢精度_Float和double丢失精度问题及解决方案

    出现这种结果的原因:float和double类型尤其不适合用于货币运算,因为要让一个float或double精确的表示0.1或者任何其他负数次方值是不可能的(十进制系统中不能准确的表示出1/3,同样二 ...

  3. java double 运算精度问题_关于java中Double类型的运算精度问题

    如果我们编译运行下面这个程序会看到什么? public class Test{     public static void main(String args[]){         System.o ...

  4. java小数丢失精度_Java中的小数运算与精度损失

    float.double类型的问题 我们都知道,计算机是使用二进制存储数据的.而平常生活中,大多数情况下我们都是使用的十进制,因此计算机显示给我们看的内容大多数也是十进制的,这就使得很多时候数据需要在 ...

  5. java double 的精度_Java Double的精度问题

    Java.text 类 DecimalFormat java.lang.Object java.text.Format java.text.NumberFormat java.text.Decimal ...

  6. Java Double类型计算工具类 BigDecimal

    BigDecimal 处理Double类型的基本运算 BigDecimal 处理Double类型的基本运算 Java Double 数据在进行数据计算的时候,很容出现丢失精度的问题,因此借助于BigD ...

  7. Java中double类型精度丢失的问题_double类型数据加减操作精度丢失解决方法_BigDecimal取整

    BigDecimal在用double做入参的时候,二进制无法精确地表示十进制小数,编译器读到字符串"0.0000002"和"1.0000002"之后,必须把它转 ...

  8. 计算价格, java中浮点数精度丢失的解决方案

    计算价格, java中浮点数精度丢失的解决方案 转载于:https://www.cnblogs.com/gloryhope/p/9896719.html

  9. Java double 保留一个小数、理解BigDecimal、Java解决精度问题

    Java double 保留一个小数 两种方法 @Testpublic void test2() {double f = 234.353333000000000000000000;BigDecimal ...

最新文章

  1. 菜鸟成长之路05/06/07
  2. Ubuntu 14 配置Android Studio的快捷启动方式
  3. There is no database available的错误消息
  4. 【Java】关于Java的一些基础知识点
  5. FTA故障树分析法-DFMEA的另外一张脸
  6. SDN核心技术与内容
  7. HTML-坐标的含义,以及变换的使用
  8. Python股票基金数据分析 爬虫 基金对比 Django框架 数据可视化
  9. python基础学习(一)
  10. VMware 安装失败解决方案,亲测有效
  11. 一篇入门Android UI 设计
  12. 信息安全体系建设☞数据完整性检查--信息安全开源工具分享
  13. Hole_making基于特征加工
  14. python语言表白超炫图形_经验分享 篇二:三分钟教你用Excel制作各种尺寸、底色的证件照...
  15. matlab excel 单元居中,用matlab如何识别excel里的单元格是否为合并单元格|excel表格怎么调整行高和列宽...
  16. 交易订单处理失败,请稍后再试(ali64)
  17. 【推免攻略】五.2022年北交计算机学院夏令营、预推免保研经验
  18. opencv 实现 Photoshop 亮度 对比度 调节功能
  19. WBC世界棒球经典赛
  20. 理查德30多岁开发出C语言,《C语言程序设计》多媒体教学课件开发与应用

热门文章

  1. Linux企业运维篇——git+gitlab+jenkins+docker构成持续集成环境
  2. 使用决策树算法预测西瓜的好坏
  3. scala中sorted,sortby,sortwith的用法(转)
  4. TIP 2021 | 重访CV经典!首个无监督深度学习图像拼接框架
  5. linux服务器拷机测试,服务器拷机使用方法
  6. matlab实验报告井字棋,有偿井字棋游戏300+
  7. -bash: unzip: command not found的错误解决方式
  8. 简历中的工作经历要怎么写?
  9. [论文阅读笔记]Deep Neural Networks are Easily Fooled:High Confidence Predictions for Unrecognizable Images
  10. C盘爆满上热搜,简单几招释放几十G空间,一下子就不红了