如果需要精确的答案,请避免使用float和double

Java中的简单浮点数类型float和double不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上面的错误。现在终于理解为什么要有BCD码了。
这个问题相当严重,如果你有9.999999999999元,你的计算机是不会认为你可以购买10元的商品的。
在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。现在让我们看看如何解决这个问题。
四舍五入
我们的第一个反应是做四舍五入。Math类中的round方法不能设置保留几位小数,我们只能象这样(保留两位):
public double round(double value){
return Math.round(value*100)/100.0;
}
非常不幸,上面的代码并不能正常工作,给这个方法传入4.015它将返回4.01而不是4.02,如我们在上面看到的
4.015*100=401.49999999999994
因此如果我们要做到精确的四舍五入,不能利用简单类型做任何运算
java.text.DecimalFormat也不能解决这个问题:
System.out.println(new java.text.DecimalFormat("0.00").format(4.025));
输出是4.02
二、精确计算
在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal
我们如果需要精确计算,使用BigDecimal或者long或者int


如果需要精确的答案,请避免使用float和double的更多相关文章
- Effective Java 第三版——60. 需要精确的结果时避免使用float和double类型
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 第48条:如果需要精确的答案,请避免使用float和double
float和double主要为了科学计算和工程计算而设计,执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不适合用于需要精确 ...
- 第四十八条:如果需要精确的答案,请避免使用float和double
让一个float或者double精确的表示0.1或者10的任何负数次方值都是不可能.float和double它们执行二进制浮点运算, 它们是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的 ...
- 不要在精确计算中使用float和double类型
http://blog.csdn.net/androiddevelop/article/details/8478879 一 问题描述 float和double类型不能用于精确计算,其主要目的是为了科 ...
- Java中浮点型数据Float和Double进行精确计算的问题
Java中浮点型数据Float和Double进行精确计算的问题 来源 https://www.cnblogs.com/banxian/p/3781130.html 一.浮点计算中发生精度丢失 ...
- 14、Java中用浮点型数据Float和Double进行精确计算时的精度问题
一.浮点计算中发生精度丢失 大概很多有编程经验的朋友都对这个问题不陌生了:无论你使用的是什么编程语言,在使用浮点型数据进行精确计算时,你都有可能遇到计算结果出错的情况.来看下面的例子. // 这是一个 ...
- 精确计算java中float和double的精度
[本文相关的代码放在github上.地址为:https://github.com/VigourJiang/StructuredFloat] Java中double类型的格式基本遵循IEEE 754标准 ...
- 不能使用 float 和 double 来表示金额等精确的值
不能使用 float 和 double 来表示金额等精确的值 关于面试,金额用什么数据类型? 不是 doube,更不是 float ,而是用 BigDecimal.对于金融项目,对于金额,误差是不能容 ...
- Effective Java 之-----精确的答案与double&float
题目: 假设你口袋里有1$,看到货架上有一排美味的糖果,标价分别为0.10$,0.20$,0.30$...1$,你打算从标价为0.10$的糖果开始买起,每种买一颗,一直到不能支付货架上下一种价格的糖果 ...
随机推荐
- Android WebSocket开发
一,在模块build.gradle中添加webSocket的依赖包 //WebSocket 依赖包 implementation 'com.neovisionaries:nv-websocket-cl ...
- fedora 28/29 配置 C++ 环境
最近 使用C++ 开发 更换机器的时候,还要重新配置一下 gnu 工具链.于是简单进行了安装了一下: yum install gcc yum install gcc-c++ yum install g ...
- 数据挖掘---Numpy的学习
什么是Numpy NumPy系统是Python的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵(任意维度的数据处理),比Python自身的嵌套列表(nested list structure ...
- February 23rd, 2018 Week 8th Friday
It takes a strong man to save himself, and a great man to save another. 强者自救,圣者渡人. When you are not ...
- contenteditable元素的placeholder输入提示语设置
在某些情况下,textarea是不够用的,我们还需要显示一些图标或者高亮元素,这就需要用富文本编辑器,而富文本编辑器本质上是HTML元素设置了contenteditable. 然后可能需要像input ...
- Jenkins的环境部署
一.Tomcat环境安装 1.安装JDK(Java环境) JDK下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index. ...
- SICP 习题 (1.43)解题总结
SICP 习题 1.43 是前面两道题的延续,习题要求我们定义一个过程(repeat f n) .当中f是一个单參数过程.题目要求我们通过repeat过程将过程f调用n次,注意是嵌套调用n次,不是连续 ...
- 重新安装liteide后无法关联.go文件的解决办法(及更改liteide配色方案)
现象:双击.go文件,从打开方式中选择新安装的liteide.exe无效. 解决办法: 打开regedit 找到HKCU\Software\Classes\go_auto_file 发现下面有shel ...
- [2] TensorFlow 向前传播算法(forward-propagation)与反向传播算法(back-propagation)
TensorFlow Playground http://playground.tensorflow.org 帮助更好的理解,游乐场Playground可以实现可视化训练过程的工具 TensorFlo ...
- emqtt在centos6下的安装
1 emqtt下载地址 http://www.emqtt.com/downloads 右键 复制链接 http://www.emqtt.com/downloads/3011/centos6 2 打开服 ...