直接上代码
public static void main(String[] args) {
System.out.println(1.0 - 0.1);
System.out.println(1.0 - 0.2);
System.out.println(1.0 - 0.3);
System.out.println(1.0 - 0.4);
System.out.println(1.0 - 0.5);
System.out.println(1.0 - 0.6);
System.out.println(1.0 - 0.7);
System.out.println(1.0 - 0.8);
System.out.println(1.0 - 0.9);
System.out.println(1.0 - 1.0);
}
最后输出的结果为神马是
0.9
0.8
0.7
0.6
0.5
0.4
0.30000000000000004
0.19999999999999996
0.09999999999999998
0.0
为什么呢?
简单的说,问题处在"
IEEE 754 floating-point arithmetic",虽然在java是遵循这个规则的,但是java语言的实现,并不是使用小数点或者十进制来表示数字,相反,它是采用分数和指数来表示,而且是
引用
uses binary fractions and exponents to represent
使用二进制的,我们可以举个例子:
0.5 = 1/2
0.75 = 1/2 + 1/(2^2)
0.85 = 1/2 + 1/(2^2) + 1/(2^3)
0.1 = 1/(2^4) + 1/(2^5) + 1/(2^8) + ...
注意,0.1只能是无限循环下去的,这就意味着0.1在java里面不能够准确的用浮点数来表示,也就造成了浮点数运算上面的误差。
举个例子:
if (0.1 + 0.1 + 0.1 != 0.3)
System.out.println("0.1 + 0.1 + 0.1 is not equal with 0.3");
else
System.out.println("0.1 + 0.1 + 0.1 is equal to 0.3");
每个人都知道,0.1 + 0.1 + 0.1 == 0.3,但是在java的实际结果却不是这样。
更深入的话
有人会问,为什么
System.out.println(0.1f);
输出的还是0.1呢?
因为在源代码里面println调用的是Float#toString(float),最终的实现是在
public static String toString(float f) {
return new FloatingDecimal(f).toJavaFormatString();
}
有兴趣的童鞋可以去阅读源代码,FloatingDecimal帮你做了很多事情。
这也牵涉出另外一个话题,如何避免上面出现的问题,
对的,就是
BigDecimal,关于BigDecimal,我相信你们在api上面会找到更多的答案。
题外话
用
BigDecimal(java.lang.String)
不要用
BigDecimal(double) or BigDecimal(float)
为什么呢?API上面写的很清楚了
引用
The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
所以
System.out.println(new BigDecimal(0.1f));
System.out.println(new BigDecimal("0.1"));
System.out.println(0.1f);
结果是不一样的
更加更加更加深入的话
if (0.1f + 0.1f + 0.1f != 0.3f)
System.out.println("0.1 + 0.1 + 0.1 is not equal to 0.3");
else
System.out.println("0.1 + 0.1 + 0.1 is equal to 0.3");
if (0.1 + 0.1 != 0.2)
System.out.println("0.1 + 0.1 is not equal to 0.2");
else
System.out.println("0.1 + 0.1 is equal to 0.2");
为何上面两串代码输出不一样?
为何0.3d就不能用3个0.1d相加,而0.2d就可以用2个0.1d相加呢?
原因的话,自己看下面的输出了
System.out.println(new BigDecimal(0.2d));
System.out.println(new BigDecimal(0.1d).add(new BigDecimal(0.1d)));
System.out.println(new BigDecimal(0.2f));
System.out.println(new BigDecimal(0.1f).add(new BigDecimal(0.1f)));
System.out.println(new BigDecimal(0.3d));
System.out.println(new BigDecimal(0.1d).add(new BigDecimal(0.1d)).add(new BigDecimal(0.1d)));
System.out.println(new BigDecimal(0.3f));
System.out.println(new BigDecimal(0.1f).add(new BigDecimal(0.1f)).add(new BigDecimal(0.1f)));
分享到:
相关推荐
iftop-1.0-0.7.pre4.el6.x86_64
【标题】"flazr-0.7-RC2.zip" 指的是一个名为 "flazr" 的软件的版本0.7的第二个候选发布版本(Release Candidate 2),其格式为ZIP压缩文件。在软件开发中,RC版本通常是在正式版发布前的最后一个测试版本,意味着该...
赠送jar包:RoaringBitmap-0.7.45.jar; 赠送原API文档:RoaringBitmap-0.7.45-javadoc.jar; 赠送源代码:RoaringBitmap-0.7.45-sources.jar; 赠送Maven依赖信息文件:RoaringBitmap-0.7.45.pom; 包含翻译后的API...
将 jpgc-graphs-basic-2.0.zip 解压缩后只有一个 lib 目录,该目录下有一个 ext 文件夹和一个 jmeter-plugins-cmn-jmeter-0.3.jar 包,ext 文件夹中有 jmeter-plugins-graphs-basic-2.0.jar 和 jmeter-plugins-...
离线安装包,亲测可用
离线安装包,亲测可用
junrar-0.7.jar 从 https://repo1.maven.org/maven2/com/github/junrar/junrar/0.7/junrar-0.7.jar 下载下来的。不过unrar的话只试用rar4.0及以下的解压哦
离线安装包,亲测可用
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
在这个标题为“redis-desktop-manager-0.7.6.15”的资源中,我们找到了该工具的一个特定版本——0.7.6.15,特别指出它在Windows 7操作系统上已经过测试并可以正常运行。 Redis Desktop Manager的主要功能包括: 1....
早期的FreeNAS-i386-LiveCD-0.7.1.5127.iso,7.1版本镜像,占用资源小
"PyPI 官网下载 | projectYash-1.0.0.7-py3-none-any.whl"这个标题指的是从Python的包索引服务(PyPI)上下载的名为"projectYash"的软件包的特定版本。PyPI是Python开发者发布和分享自己编写的开源软件的地方,它为...
modify_headers-0.7.1.1-fx.xpi 火狐插件,模拟外网进行相关的测试工作。
资源分类:Python库 所属语言:Python 资源全名:improviser-0.7.0.3.win32.exe 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
adblock__plus-0.7.5.5-fx+fl+zm+sg+tb.xpi
在信息技术日益发展的今天,各种开源项目层出不穷,其中d2r-server-0.7作为一款备受瞩目的服务器软件,为数据处理和信息交换提供了强大的支持。本文将详细介绍d2r-server-0.7的安装过程及其核心功能,帮助读者更好地...
适用于 Android 语音识别,...3、sphinxbase-0.7 4、cmuclmtk-0.7-win32 5、pocketsphinx-0.7 6、PocketSphinxAndroidDemo 具体使用参照博客文章: http://gaebolg.blog.163.com/blog/static/19826906820136232810723/
GosuncnWelink_Driver_Release_1.0.0.7(1).exe