2019独角兽企业重金招聘Python工程师标准>>>

关于Java浮点数运算精度丢失问题 博客分类: java

前几天看了一个朋友的博客,说Java中浮点数运算精度丢失的问题,他给出了问题,也指出了C语言相对于Java的优势,其实,Java中也是可以解决浮点运算精度丢失问题的。

那就是:BigDecimal。

先看一段程序:

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

上面的程序运行结果是:

上面程序运行结果表明,Java的double类型会发生精度丢失问题,其实,不尽是Java,很多编程语言都存在这样的问题。

为了能精确的表示、计算浮点数,Java提供了BigDecimal类,该类提供了大量的构造器用于创建BigDecimal对象,包括把所有的基本类型转换层一个BigDecimal对象,也包括利用数字字符串、数字字符数组来创建BigDecimal对象。详细介绍请查阅API手册。

双精度浮点型变量 double 可以处理 16 位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。 Java 在 java.math 包中提 供的 API 类 BigDecimal ,用来对超过 16 位有效位的数进行精确的运算。表 5.7 中列出了 BigDecimal 类的主要构造器和方法。

构造器描述 : 
BigDecimal(int) 创建一个具有参数所指定整数值的对象。  
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。  
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。  
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。

方法描述 : 
add(BigDecimal)BigDecimal 对象中的值相加,然后返回这个对象。  
subtract(BigDecimal)BigDecimal 对象中的值相减,然后返回这个对象。  
multiply(BigDecimal)BigDecimal 对象中的值相乘,然后返回这个对象。  
divide(BigDecimal)BigDecimal 对象中的值相除,然后返回这个对象。  
toString() 将 BigDecimal 对象的数值转换成字符串。  
doubleValue() 将 BigDecimal 对象中的值以双精度数返回。

示例程序:

public class BigDecimalTest
{
public static void main(String[] args)
{
BigDecimal f1 = new BigDecimal("0.05");
BigDecimal f2 = BigDecimal.valueOf(0.01);
BigDecimal f3 = new BigDecimal(0.05);
System.out.println("使用String作为BigDecimal构造器参数:");
System.out.println("0.05 + 0.01 = " + f1.add(f2));
System.out.println("0.05 - 0.01 = " + f1.subtract(f2));
System.out.println("0.05 * 0.01 = " + f1.multiply(f2));
System.out.println("0.05 / 0.01 = " + f1.divide(f2));
System.out.println("使用double作为BigDecimal构造器参数:");
System.out.println("0.05 + 0.01 = " + f3.add(f2));
System.out.println("0.05 - 0.01 = " + f3.subtract(f2));
System.out.println("0.05 * 0.01 = " + f3.multiply(f2));
System.out.println("0.05 / 0.01 = " + f3.divide(f2));
}
}

程序运行结果:

从上面的运行结果可以看出,BigDecimal进行算术运算的效果,而且,在创建BigDecimal对象时,一定要使用String对象作为构造器参数,而不是直接使用double数字。

API手册中是这样解释的:

注:

public BigDecimal(double val)
  1. 此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double (或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样, 传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
  2. 另一方面, String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal ,它 正好 等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法 。
  3. 当 double 必须用作 BigDecimal 的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用 Double.toString(double) 方法,然后使用 BigDecimal(String) 构造方法,将 double 转换为 String 。要获取该结果,请使用 static valueOf(double) 方法。

http://www.tuicool.com/articles/nAFr6r

转载于:https://my.oschina.net/xiaominmin/blog/1599134

关于Java浮点数运算精度丢失问题相关推荐

  1. 浮点数运算精度丢失的问题

    导入 在我们平时编码的过程中,你一定遇到过这样的问题: const a = 0.1; const b = 0.2; console.log(a + b); // 0.30000000000000004 ...

  2. PHP浮点数运算精度问题

    最近有客户反应商城订单金额总是不准确,总是相隔一分钱.检查相关代码逻辑都是正确的,就是运用了四则运算.大概推测问题可能出在浮点计算丢失精度.在<PHP程序员雷雪松的博客>中写过一篇关于JS ...

  3. 浮点数的运算精度丢失

    引出 打开Python编译器,输入 0.1+0.2, 期待的结果是0.3,但是输出为: 0.30000000000000004 有点小尴尬,这是为什么呢? 解惑 其实这设计到了计算机的浮点数存储是以二 ...

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

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

  5. java 浮点数运算_对于同样的浮点数运算为何 Java 与 C 的结果不相同?

    @bombless 在问题的评论里写得没错.IEEE 754最重要的(大家基本上遵守的)是数据的格式.虽然也有算法上的指引(例如有各种rounding mode),但实际上大家实现得不一定那么严格. ...

  6. Java浮点数运算工具类

    import java.math.BigDecimal; import java.math.RoundingMode;/*** 精确的浮点数运算*/ public class Arith {/** 默 ...

  7. js中浮点数运算精度问题

    在js中,我们有时会遇到计算,通过加减乘除处理某些业务.那么这时候如果不做任何处理,就会出现如下典型的精度丢失问题. console.log(0.1 + 0.2) ; // 0.30000000000 ...

  8. java long double精度丢失_long long类型转double类型部分精度丢失问题

    我最近做了一道题,一个64位(unsigned __int64)范围内的数输出其除以1000的值,并按四舍五入保留小数点后三位. 我刚开始直接写WA,结果发现当数比较大的时候,结果后几位精度总会丢失, ...

  9. MATLAB浮点数运算精度问题

    matlab计算题:              而后用matlab进行了一些浮点数计算,但结果都出乎预料:          2+2*eps = 2.000          3 + eps = 3 ...

最新文章

  1. 听听阿里老哥对算法工程师技术学习路线的建议
  2. 【转】C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁
  3. 毕业了,就忘掉导师吧
  4. python安装库的方法linalg_Python linalg.gmres方法代码示例
  5. java.sql.preparedstatement的应用
  6. 台达b3伺服参数设置方法,台达B2伺服电机参数设定
  7. Python:人工智能库如何选择,百度图像识别入门
  8. IDEA 2020 返回上一步快捷键
  9. 计算机语音发展,计算机语音合成技术研究及发展方向
  10. 20.6.5算法心得 一元二次方程解法
  11. (九)DFI接口时序
  12. Unity2019安卓平台新手安装设置建议
  13. matlab中tdma源程序,40MF-TDMA系统中多用户多业务的无线接入控制和时隙分配算法MATLAB源代码...
  14. 快点来学吧!9次Android面试经验总结,已开源
  15. 二手平台android界面,Android二手书交易app设计(2)启动图Activity
  16. Hive经典最全笔试题系列
  17. 基于VUE的音乐播放器
  18. 大数据入门之分布式计算框架Spark(2) -- Spark SQL
  19. 论文 | 图理论 | 2021年斯坦福大学Jiaxuan You博士论文《用图赋能深度学习》译读 摘要和感谢
  20. JavaScript期末大作业 罗兰永恒花园动漫价绍网页 7页,含有table表格,js表单验证还有首页视频

热门文章

  1. python 的csr_Python scipy.sparse.csr_matrix()[csc_matrix()]
  2. atom配置python环境_Python编程:用VScode配置Python开发环境
  3. 源生php怎么打印,PHP如何实现云打印
  4. 学报格式和论文格式一样吗_社科类学报字数要求及投稿注意事项
  5. 用FTP命令进行文件批量上传或下载
  6. 新增一个主键自增长_使用技巧之——MyBatis如何返回插入主键
  7. centos7解压安装mysql_CentOS7 安装Mysql5.7 解压缩版
  8. Chika and Friendly Pairs(莫队+树状数组+离散化+预处理上下界)
  9. 计算机三级之嵌入式系统学习笔记5
  10. Spring Boot整合Swagger3