一直以来都没有机会做非常需要精确计算的项目,所以对常用的浮点数计算没什么经验。刚看书时发现一个有趣的现象,特写出来与大家分享,可能有些高手会觉得小儿科,但我希望不知道的朋友多注意下。
demo1:
public static void demo1() {
double a = 1.01;
double b = 2.01;
System.out.println(a + b);
System.out.println();
}
大家运行出来結果应该是3.0199999999999996,而不是3.02.其实代码都没错,只是计算机存储浮点数时是用二进制的,所有的数都保存为以2的N次方。0.5很好表示(2的-1次方),但0.1就没那么好精确了。
有兴趣的朋友可以看一下1.01, 2.01,1.01+2.01, 3.02 的二进制表示有什么区别,你会发现3.02和1.01+2.01的最后一个bit不同。
说了这么多怎么解决精确计算呢?其实java为我们提供了Decimal类与BigDecimal类就是来解决精确计算的,当然精确计算肯定会相对计算慢一些,但如果你要精确计算,你自己权衡一下是要精确还是要性能。
demo2:
public static void demo2() {
double area;
for (int i = 1; i < 10; i++) {
area = 3.14 * i * i;
System.out.println("圆的半径为" + i + ", 其面积为" + area);
}
System.out.println();
}
其实結果为
圆的半径为1, 其面积为3.14
圆的半径为2, 其面积为12.56
圆的半径为3, 其面积为28.259999999999998
圆的半径为4, 其面积为50.24
圆的半径为5, 其面积为78.5
圆的半径为6, 其面积为113.03999999999999
圆的半径为7, 其面积为153.86
圆的半径为8, 其面积为200.96
圆的半径为9, 其面积为254.34
现在我们把输出結果的地方加DecimalFormat类格式化一下。
demo 3:
public static void demo3() {
double area;
DecimalFormat df = new DecimalFormat("#.000");
for (int i = 1; i < 10; i++) {
area = 3.14 * i * i;
System.out.println("圆的半径为" + i + ", 其面积为" + df.format(area));
}
System.out.println();
}
输出結果为:
圆的半径为1, 其面积为3.140
圆的半径为2, 其面积为12.560
圆的半径为3, 其面积为28.260
圆的半径为4, 其面积为50.240
圆的半径为5, 其面积为78.500
圆的半径为6, 其面积为113.040
圆的半径为7, 其面积为153.860
圆的半径为8, 其面积为200.960
圆的半径为9, 其面积为254.340
結果似乎正确了,其实还没有,请看下一个。
demo4:
public static void demo4() {
double area = 24.205;
DecimalFormat df = new DecimalFormat("#.00");
System.out.println(df.format(area));
System.out.println();
}
输出結果为:24.20,不是24.21。
要想得到24.21的精确結果,推荐使用BigDecimal提供更大的或更小的数进行运算。
demo5:
public static void demo5() {
double area = 24.205;
BigDecimal bd = new BigDecimal(Double.toString(area));
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(bd.doubleValue());
System.out.println();
}
这样就对了。
看到资料上说BigDecimal推荐使用String类型来初始化构造函数,这样可以避免一些莫名其妙的异常错误。具体原因也提供了一些例子,我这里就不写了。
现在不知道在开源包中有没有进行精确计算的工具,要是哪位朋友知道有的话告诉其他朋友一下。
分享到:
相关推荐
上学时候做的一个java小程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
老师上课布置的作业,回来闷头就写,如果有人想借鉴的话,可以参考一下
一个码农的毕生所学!笔记 & 教程。考研,就业,上学.语言篇,Android,C++,Java,JavaSc 一个码农的毕生所学!笔记 & 教程。考研,就业,上学.语言篇,Android,C++,Java,JavaSc 一个码农的毕生所学!笔记 & ...
一个简单的例子:从0.0到1.0之间可以生成一个双精度浮点数。那么通过上面的信息,开发人员要产生0.0和10.0之间的双精度浮点数会这样来写: 1.Math.random() * 10 而产生0和10之间的整数,则会写成: 1.Math.round...
大三上学Java大作业 用的是java swing做前端界面 用jdbc链接mysql数据库 班级学生信息的管理 大三上学Java大作业 用的是java swing做前端界面 用jdbc链接mysql数据库 班级学生信息的管理 大三上学Java大作业 用的是...
年龄计算器是一款可以精确的计算出从你出生到现在的时间段.
Java课程设计-21点小游戏(2)全文共21页,当前为第1页。Java课程设计-21点小游戏 Java课程设计-21点小游戏(2)全文共21页,当前为第1页。 2016—2017学年 第二学期 2016—2017学年 第二学期 《面向对象程序设计》 课程...
上学时写的一个java简单的学生管理系统,都是一些基础内容,没有使用数据库,通过控制台进行操作,界面如下: ----------你要执行的功能 >---------- 1:添加一个学生 2:查找一个学生 3:根据编号更新学生的...
Java课程设计-21点小游戏 Java课程设计-21点小游戏全文共22页,当前为第1页。LT Java课程设计-21点小游戏全文共22页,当前为第1页。 Java课程设计-21点小游戏全文共22页,当前为第2页。 Java课程设计-21点小游戏全文...
无意中翻出了几年前上学时写的一个俄罗斯方块的游戏,记得是个周末写的,从头到尾用了两天。整个程序完全使用java画图,没有图片资料。声音文件来自互联网。 现公开其源代码,供初学者学习。 源代码可自由传播和...
无意中翻出了几年前上学时写的一个俄罗斯方块的游戏,记得是个周末写的,从头到尾用了两天。整个程序完全使用java画图,没有图片资料。声音文件来自互联网。 现公开其源代码,供初学者学习。 源代码可自由传播和...
写的异常简单,上学期间写的,那时候写代码可比现在激情多了。
OPP-Java 上学期间的Java学习代码
操作流程:软件有两个窗口一个是答案显示,一个是上学吧网址。 1、搜索你需要查的题目/输入上学吧题目对应id 二选一就行,哪个方便用哪个 2、切换到上学吧窗口,选择试题 3、进入试题后可以看到破解按钮,点击 4、...
socket考试系统,超漂亮...使用技术:SOCKET,STREAM,FILE,SQL等,因为只是上学时的一个期末作业,只用了两天写的代码,后来一直没有时间做,放上来只为了大家学习一下,一起学习一起进步,希望本系统能对您有所帮助,谢谢支持...
java网页抓取数据
java上大学时候的ppt,现在共享下 有需要的过来下载吧
一个码农的毕生所学!笔记 & 教程。考研,就业,上学.语言篇,Android,C++,Java,JavaScript,Latex,MATLAB,NodeJS,PHP,Python,技术篇,docker,git,Linux,Maven,office,Spark,Spring,….zip一个码农的毕生所学!笔记 &...
书上学不到的46条保命驾驶技巧.doc
这是Java2实用教程的课后答案。因为这本教材太经典了,基本上学Java的人都知道这本书,所以分享一下课后的答案。