`
zhoutaomtv
  • 浏览: 11944 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

刚从书上学到的一个小点:Java中的精确计算

    博客分类:
  • java
阅读更多
一直以来都没有机会做非常需要精确计算的项目,所以对常用的浮点数计算没什么经验。刚看书时发现一个有趣的现象,特写出来与大家分享,可能有些高手会觉得小儿科,但我希望不知道的朋友多注意下。

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小程序qq

    【标题】"上学时候做的一个java小程序qq"指的是一个基于Java编程语言开发的网络聊天应用程序,可能是作者在学习阶段为了实践Java网络编程和模仿QQ聊天功能而创建的一个小型项目。这个程序可能包含了基本的用户注册、...

    Java语言课程设计任务书及题目

    设计一个图形用户界面的计算器,涉及到事件监听、布局管理以及算术运算逻辑,是GUI编程和算法实现的实战演练。 **知识点11:画随机的圆** 通过实现动态变化的圆形动画,学生可以深入了解Java图形库的使用,掌握...

    java小游戏jar

    总的来说,【Java小游戏Jar】是一个体现Java编程基础和游戏开发原理的实例,对于初学者来说,它提供了一个实际应用所学知识的平台,同时也能锻炼解决问题和逻辑思考的能力。通过分析和改进这样的项目,开发者可以...

    JAVA语言程序设计实验指导书

    - 开发一个购物结算系统,能够计算商品总价、添加折扣等功能。 #### 3.11 综合型实验 - **题目一:学生成绩管理系统的设计** - 实现一个学生成绩管理系统,包括成绩录入、查询、统计等功能。 - **题目二:Socket...

    java上学时候的ppt

    Java是一种广泛使用的高级编程语言,由Sun Microsystems(后被Oracle公司收购)于1995年发布。它的设计目标是“一次编写,到处运行”,强调跨平台的可...这个“java上学时候的ppt”无疑是学习Java语言的一个宝贵资源。

    java编写21点游戏(附源代码)

    Java编写的21点游戏是一款基于概率和策略的桌面小游戏,其规则简单,但具有一定的挑战性。在Java编程中实现这样的游戏可以帮助初学者更好地理解面向对象编程、事件处理、控制流以及游戏逻辑的设计。以下将详细介绍这...

    年龄计算器 精确计算出您的时间段

    年龄计算器是一种应用软件,主要功能是根据用户输入的出生日期,精确地计算出从出生到当前日期的时间差,通常以年、月、日的形式展示。这个工具不仅适用于个人使用,了解自己的年龄,还可以用于各种需要计算年龄差的...

    java编写的斗地主小游戏.zip

    在完成斗地主小游戏的过程中,学生需要将课堂上学到的Java编程知识、软件工程原理、算法设计等应用到实际项目中。同时,它也是一个良好的机会来提升问题解决、团队协作和文档编写等软技能。 5. 练手学习:对于初学...

    《毕业设计》-一个码农的毕生所学!笔记 &amp; 教程 考研,就业,上学.语言篇,Android,C++,Java,Java

    一个码农的毕生所学!笔记 &amp; 教程。考研,就业,上学.语言篇,Android,C++,Java,JavaSc 一个码农的毕生所学!笔记 &amp; 教程。考研,就业,上学.语言篇,Android,C++,Java,JavaSc 一个码农的毕生所学!笔记 &amp; ...

    java新手小游戏.zip

    在这个"java新手小游戏.zip"压缩包中,我们可以看到一个针对Java初学者的游戏开发项目,这将是一个很好的实践机会,可以加深对编程概念的理解。 描述中提到的游戏开发是计算机科学的一个重要分支,它涉及到动画、...

    OPP-Java:上学期间的Java学习代码

    在"OPP-Java:上学期间的Java学习代码"中,很可能包含了上述知识点的实践示例,可能覆盖了基础到进阶的Java编程技能。通过这个项目,你可以深入理解Java编程,从简单的控制结构到复杂的面向对象设计模式,提升自己的...

    java初级程序设计(和各位分享)

    Java初级程序设计主要涵盖以下几个核心知识点: 1. **Java简介**:Java是一种广泛使用的面向对象...通过查看这些文件,你可以回顾和巩固你在课堂上学到的知识点,同时也可以看到编程实践中可能遇到的问题和解决策略。

    java计算机课程毕业设计学习源代码day13.7z

    标题中的"java计算机课程毕业设计学习源代码day13.7z"表明这是一个与Java编程相关的学习资源,可能是一个教学项目或课程的一部分,专注于毕业设计。这个7z压缩包包含了多个Java类文件,这些文件是Java应用程序的基础...

    java+Swing+sql2005房屋管理系统

    【标题】:“java+Swing+...总的来说,"java+Swing+sql2005房屋管理系统"是一个全面展示Java桌面应用开发流程的实例,涵盖了从界面设计到后台数据处理的各个环节,对于学习和提高Java和数据库技术有着重要的参考价值。

    java计算机课程毕业设计学习源代码day07.7z

    - 标签中提到的“软件/插件”可能意味着这些源代码最终将被集成到一个更大的软件系统中,或者`Watch`和`NewWatch`类可能作为其他程序的组件,即插件。 8. **课程资源**: - 这些文件作为课程资源,不仅提供了实际...

    java简单排课系统源码

    Java简单排课系统源码是一个基于Java Swing和 SWT(Standard Widget Toolkit)库开发的应用程序,主要...此外,对于初学者来说,这是一个很好的动手项目,可以巩固课堂上学到的理论知识,并提升实际解决问题的能力。

    java 课堂练习备份工程

    4. **JdbcDemo**:这是一个关于Java数据库连接(JDBC)的示例,可能包括数据库连接、SQL查询、结果集处理、预编译语句(PreparedStatement)的使用等。通过这个练习,学习者可以了解如何与各种关系型数据库进行交互...

    java视频教程_黑马Java零基础辅导班[第一期]第2天课件源码

    【标题】"java视频教程_黑马Java零基础辅导班[第一期]第2天课件源码" 提供的是一个针对初学者的Java编程教学资源,由知名教育机构"黑马"提供,旨在帮助完全没有Java背景的学员快速入门。课程内容可能是以视频的形式...

    java网页抓取数据

    Java网页抓取数据是互联网数据挖掘的一个重要领域,它允许开发者通过编程方式获取网页上的信息,从而实现自动化分析、监控或构建智能应用。在Java中,我们通常使用HTTP客户端库和HTML解析工具来实现这一目标。本文将...

Global site tag (gtag.js) - Google Analytics