在项目当中,对于double类型数据的使用比较频繁。尤其是处理金钱相关的数据,在使用Double类型的数据时,涉及到精度,显示,四舍五入等等问题。

1.  显示问题,当double 数据 小于 0.0001 大于等于 10000000时,直接转为String输出时,会显示为科学计数法。

   1:  double double1 = 0.00009;
   2:  System.out.println(double1); // 9.0E-5
   3:         
   4:  double double2 = 10000000;
   5:  System.out.println(double2); // 1.0E7

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

需要使用DecimalFormat 转化输出

   1:  DecimalFormat formate = new DecimalFormat("#.######");
   2:  System.out.println(formate.format(double1)); //0.00009
   3:          
   4:  formate = new DecimalFormat("########.##");
   5:  System.out.println(formate.format(double2));//10000000
 
这里面会有四舍五入问题:
   1:  double double1 = 0.000096789;
   2:  DecimalFormat formate = new DecimalFormat("#.######");
   3:  System.out.println(formate.format(double1)); //0.000097

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

当取小数点后六位时,会在第七位四舍五入。

2. 误差问题,两个Double类型的数,进行运算。经常会产生误差。

   1:  System.out.println(0.05 + 0.01); //0.060000000000000005
   2:  System.out.println(1.0 - 0.42);  //0.5800000000000001
   3:  System.out.println(4.015 * 100); //401.49999999999994
   4:  System.out.println(123.3 / 100); //1.2329999999999999

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

看似简单的计算,结果却出人意料。解决方法是将Double转为BigDecimal。调用BigDecimal的 运算。

   1:   double d1 = 0.05;
   2:   double d2 = 0.01;
   3:   BigDecimal b1 = new BigDecimal(Double.toString(d1));
   4:   BigDecimal b2 = new BigDecimal(Double.toString(d2));
   5:   System.out.println(b1.add(b2));  //0.06
 
需要注意的是,如果new BigDecimal()时使用的是double类型的构造方法。问题依旧是可能存在的,这边要使用String参数的构造方法。
 
3. 两个double比较的问题。将double数的运算结果和0比较。由于精度问题,比如if(1-0.999999999999999999 == 0.0) 这个是成立的。
 
附上double数的运算:
   1:      /**
   2:       * 两个Double数相加
   3:       * 
   4:       * @param v1
   5:       * @param v2
   6:       * @return
   7:       */
   8:      public static double doubleAdd(Double v1, Double v2) {
   9:   
  10:          BigDecimal b1 = new BigDecimal(v1.toString());
  11:   
  12:          BigDecimal b2 = new BigDecimal(v2.toString());
  13:   
  14:          return b1.add(b2).doubleValue();
  15:   
  16:      }
  17:   
  18:      /**
  19:       * 两个Double数相减
  20:       * 
  21:       * @param v1
  22:       * @param v2
  23:       * @return
  24:       */
  25:      public static double doubleSub(Double v1, Double v2) {
  26:   
  27:          BigDecimal b1 = new BigDecimal(v1.toString());
  28:   
  29:          BigDecimal b2 = new BigDecimal(v2.toString());
  30:   
  31:          return b1.subtract(b2).doubleValue();
  32:   
  33:      }
  34:   
  35:      /**
  36:       * 两个Double数相乘
  37:       * 
  38:       * @param v1
  39:       * @param v2
  40:       * @return
  41:       */
  42:      public static double doubleMul(Double v1, Double v2) {
  43:   
  44:          BigDecimal b1 = new BigDecimal(v1.toString());
  45:   
  46:          BigDecimal b2 = new BigDecimal(v2.toString());
  47:   
  48:          return b1.multiply(b2).doubleValue();
  49:   
  50:      }
  51:   
  52:      /**
  53:       * 两个Double数相除
  54:       * 
  55:       * @param v1
  56:       * @param v2
  57:       * @return
  58:       */
  59:      public static double doubleDiv(Double v1, Double v2) {
  60:   
  61:          BigDecimal b1 = new BigDecimal(v1.toString());
  62:   
  63:          BigDecimal b2 = new BigDecimal(v2.toString());
  64:   
  65:          return b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP)
  66:                  .doubleValue();
  67:   
  68:      }
  69:   
  70:      /**
  71:       * 两个Double数相除,并保留scale位小数
  72:       * 
  73:       * @param v1
  74:       * @param v2
  75:       * @param scale
  76:       * @return
  77:       */
  78:      public static double doubleDiv(Double v1, Double v2, int scale) {
  79:   
  80:          if (scale < 0) {
  81:   
  82:              throw new IllegalArgumentException(
  83:   
  84:              "The scale must be a positive integer or zero");
  85:   
  86:          }
  87:          int DEF_DIV_SCALE = 10;
  88:   
  89:          BigDecimal b1 = new BigDecimal(v1.toString());
  90:   
  91:          BigDecimal b2 = new BigDecimal(v2.toString());
  92:   
  93:          return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
  94:   
  95:      }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Java 中 Double 相关问题的更多相关文章

  1. java中double变量保留小数问题

    (转载自玄影池扁舟) 做java项目的时候可能经常会遇到double类型变量保留小数的问题,下面便把我的经验做个简短的总结: java中double类型变量保留小数问题大体分两种情况: (一):小数点 ...

  2. Java中double类型的数据精确到小数点后两位

    Java中double类型的数据精确到小数点后两位 多余位四舍五入,四种方法 一: double f = 111231.5585;BigDecimal b = new BigDecimal(f); d ...

  3. Java中double变量精确到小数点后几(2)位

    import java.math.BigDecimal; import java.text.NumberFormat; public class Java中double类型的数据精确到小数点后两位 { ...

  4. 【Socket编程】Java中网络相关API的应用

    Java中网络相关API的应用 一.InetAddress类 InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址. InetAddress类没有构造方法,所以不能直接new出 ...

  5. 关于java中Double类型的运算精度问题

    标题     在Java中实现浮点数的精确计算    AYellow(原作) 修改    关键字     Java 浮点数 精确计算   问题的提出:如果我们编译运行下面这个程序会看到什么?publi ...

  6. Java中Double类型计算问题

    public class Test{    public static void main(String args[]){        System.out.println(0.05+0.01);  ...

  7. 如何使java中double类型不以科学计数法表示

    在java中,把一个double或者BigDecimal的小数转换为字符串时,经常会用科学计数法表示,而我们一般不想使用科学计数法,可以通过:DecimalFormat a = new Decimal ...

  8. 关于java中Double类型的运算精度问题(转)

    Java Java double:浮点数:精确计算  public class Test{    public static void main(String args[]){        Syst ...

  9. JAVA中double类型运算结果异常的解决

    问题: 对两个double类型的值进行运算,有时会出现结果值异常的问题.比如: System.out.println(19.99+20); System.out.println(1.0-0.66); ...

随机推荐

  1. rest framework 权限

    一.权限示例 需求:不同的用户类型有不同的权限 普通用户:只能查看个人信息相关,序号:1 VIP 用户:只能查看个人信息相关,序号:2 SVIP 用户:查看订单相关信息,序号:3 1.新建 app/u ...

  2. 连接mysql时报:message from server: "Host '192.168.76.89' is not allowed to connect to this MySQL server 处理方案

    1.先用localhost方式连接到MySQL数据库,然后使用MySQL自带的数据库mysql; use mysql: 2.执行:select host from user where user = ...

  3. C++内存管理之unique_ptr

    一个unique_ptr"拥有“他所指向的对象.与shared_ptr不同,某个时刻只能有一个unique_ptr指向一个给定的对象.当unique_ptr被销毁时,它所指向的对象也被销毁. ...

  4. docker17.09.1-ce 执行systemctl resart docker重启失败的问题

    记录在实际操作中碰到的docker问题 环境信息: 安装完kolla ocata版本,并且编译成功各openstack 组件的容器镜像 [root@localhost ~]# docker --ver ...

  5. PHP现阶段发现的不足点

    1.php测试单元的实现(参考文档:https://blog.csdn.net/weixin_41282397/article/details/85052015)

  6. Centos7 安装MySQL 5.7 (通用二进制包)

    1.下载安装包 下载地址 https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz ...

  7. Exception异常处理

    1.java异常类: 都是Throwable的子类: 1.Exception(异常) :是程序本身可以处理的异常. 2.Error(错误): 是程序无法处理的错误.这些错误表示故障发生于虚拟机自身.或 ...

  8. 有关UPDATE操作的一些想法

    我们平常写代码的时候,无疑都会接触大量的数据CURD操作.第一反应是这太简单了,那么你在编写UPDATE操作的时候是怎样的逻辑呢?比较下面两段伪代码: code exp.1 $SQL = " ...

  9. 解读人:李琼,Metabolic profiling of tumors, sera and skeletal muscles from an orthotopic murine model of gastric cancer associated-cachexia(胃癌相关恶病质的原位小鼠模型中肿瘤,血清和骨骼肌的代谢谱分析)

    发表时间:(2019年4月) IF:3.950 单位: 厦门大学 厦门理工大学 物种:小鼠的肿瘤,血清和骨骼肌 技术:核磁共振代谢组学分析 一. 概述:(用精炼的语言描述文章的整体思路及结果) 本研究 ...

  10. Leetcode初级算法(链表篇)

    删除链表的倒数第N个节点 感觉自己对于链表的知识还是了解的不够深入,所以没有想到用双指针进行操作.我的想法是这样的,首先计算整个链表的长度,然后遍历到长度减去n的节点处,执行删除操作. 自己的代码: ...