关于Java浮点数运算精度丢失问题
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)
- 此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double (或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样, 传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
- 另一方面, String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal ,它 正好 等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法 。
- 当 double 必须用作 BigDecimal 的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用
Double.toString(double)
方法,然后使用BigDecimal(String)
构造方法,将 double 转换为 String 。要获取该结果,请使用 staticvalueOf(double)
方法。
http://www.tuicool.com/articles/nAFr6r
转载于:https://my.oschina.net/xiaominmin/blog/1599134
关于Java浮点数运算精度丢失问题相关推荐
- 浮点数运算精度丢失的问题
导入 在我们平时编码的过程中,你一定遇到过这样的问题: const a = 0.1; const b = 0.2; console.log(a + b); // 0.30000000000000004 ...
- PHP浮点数运算精度问题
最近有客户反应商城订单金额总是不准确,总是相隔一分钱.检查相关代码逻辑都是正确的,就是运用了四则运算.大概推测问题可能出在浮点计算丢失精度.在<PHP程序员雷雪松的博客>中写过一篇关于JS ...
- 浮点数的运算精度丢失
引出 打开Python编译器,输入 0.1+0.2, 期待的结果是0.3,但是输出为: 0.30000000000000004 有点小尴尬,这是为什么呢? 解惑 其实这设计到了计算机的浮点数存储是以二 ...
- java double 运算精度问题_关于java中Double类型的运算精度问题
如果我们编译运行下面这个程序会看到什么? public class Test{ public static void main(String args[]){ System.o ...
- java 浮点数运算_对于同样的浮点数运算为何 Java 与 C 的结果不相同?
@bombless 在问题的评论里写得没错.IEEE 754最重要的(大家基本上遵守的)是数据的格式.虽然也有算法上的指引(例如有各种rounding mode),但实际上大家实现得不一定那么严格. ...
- Java浮点数运算工具类
import java.math.BigDecimal; import java.math.RoundingMode;/*** 精确的浮点数运算*/ public class Arith {/** 默 ...
- js中浮点数运算精度问题
在js中,我们有时会遇到计算,通过加减乘除处理某些业务.那么这时候如果不做任何处理,就会出现如下典型的精度丢失问题. console.log(0.1 + 0.2) ; // 0.30000000000 ...
- java long double精度丢失_long long类型转double类型部分精度丢失问题
我最近做了一道题,一个64位(unsigned __int64)范围内的数输出其除以1000的值,并按四舍五入保留小数点后三位. 我刚开始直接写WA,结果发现当数比较大的时候,结果后几位精度总会丢失, ...
- MATLAB浮点数运算精度问题
matlab计算题: 而后用matlab进行了一些浮点数计算,但结果都出乎预料: 2+2*eps = 2.000 3 + eps = 3 ...
最新文章
- 听听阿里老哥对算法工程师技术学习路线的建议
- 【转】C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁
- 毕业了,就忘掉导师吧
- python安装库的方法linalg_Python linalg.gmres方法代码示例
- java.sql.preparedstatement的应用
- 台达b3伺服参数设置方法,台达B2伺服电机参数设定
- Python:人工智能库如何选择,百度图像识别入门
- IDEA 2020 返回上一步快捷键
- 计算机语音发展,计算机语音合成技术研究及发展方向
- 20.6.5算法心得 一元二次方程解法
- (九)DFI接口时序
- Unity2019安卓平台新手安装设置建议
- matlab中tdma源程序,40MF-TDMA系统中多用户多业务的无线接入控制和时隙分配算法MATLAB源代码...
- 快点来学吧!9次Android面试经验总结,已开源
- 二手平台android界面,Android二手书交易app设计(2)启动图Activity
- Hive经典最全笔试题系列
- 基于VUE的音乐播放器
- 大数据入门之分布式计算框架Spark(2) -- Spark SQL
- 论文 | 图理论 | 2021年斯坦福大学Jiaxuan You博士论文《用图赋能深度学习》译读 摘要和感谢
- JavaScript期末大作业 罗兰永恒花园动漫价绍网页 7页,含有table表格,js表单验证还有首页视频
热门文章
- python 的csr_Python scipy.sparse.csr_matrix()[csc_matrix()]
- atom配置python环境_Python编程:用VScode配置Python开发环境
- 源生php怎么打印,PHP如何实现云打印
- 学报格式和论文格式一样吗_社科类学报字数要求及投稿注意事项
- 用FTP命令进行文件批量上传或下载
- 新增一个主键自增长_使用技巧之——MyBatis如何返回插入主键
- centos7解压安装mysql_CentOS7 安装Mysql5.7 解压缩版
- Chika and Friendly Pairs(莫队+树状数组+离散化+预处理上下界)
- 计算机三级之嵌入式系统学习笔记5
- Spring Boot整合Swagger3