`

Java解惑—小数精确计算

阅读更多
http://vera8733.blog.163.com/blog/static/173698346201121491018515/

2. 小数精确计算

Java代码 
System.out.println(2.00 -1.10);//0.8999999999999999 
上面的计算出的结果不是 0.9,而是一连串的小数。问题在于1.1这个数字不能被精确表示为一个double,因此它被表示为最接近它的double值,该程序从2中减去的就是这个值,但这个计算的结果并不是最接近0.9的double值。
一般地说,问题在于并不是所有的小数都可以用二进制浮点数精确表示。
二进制浮点对于货币计算是非常不适合的,因为它不可能将1.0表示成10的其他任何负次幂。

解决问题的第一种方式是使用货币的最小单位(分)来表示:System.out.println(200-110);//90

第二种方式是使用BigDecimal,但一定要用BigDecimal(String)构造器,而千万不要用BigDecimal(double)来构造(也不能将float或double型转换成String再来使用BigDecimal(String)来构造,因为在将float或double转换成String时精度已丢失)。例如new BigDecimal(0.1),它将返回一个BigDecimal,也即0.1000000000000000055511151231257827021181583404541015625,正确使用BigDecimal,程序就可以打印出我们所期望的结果0.9:
Java代码 
System.out.println(new BigDecimal("2.0").subtract(new BigDecimal("1.10")));// 0.9 

另外,如果要比较两个浮点数的大小,要使用BigDecimal的compareTo方法。

3. int整数相乘溢出
我们计算一天中的微秒数:

Java代码 
long microsPerDay = 24 * 60 * 60 * 1000 * 1000;// 正确结果应为:86400000000 
System.out.println(microsPerDay);// 实际上为:500654080 

问题在于计算过程中溢出了。这个计算式完全是以int运算来执行的,并且只有在运算完成之后,其结果才被提升为long,而此时已经太迟:计算已经溢出。 解决方法使计算表达式的第一个因子明确为long型,这样可以强制表达式中所有的后续计算都用long运算来完成,这样结果就不会溢出:

Java代码 
long microsPerDay = 24L * 60 * 60 * 1000 * 1000; 
分享到:
评论

相关推荐

    Java解惑(中文+书签).pdf

    此外,可以使用`BigDecimal`类来处理涉及精确小数运算的情况,该类提供了精确的小数运算功能,适用于需要高精度的金融计算场景。 3. 浮点数表示和输出的特殊规则 文档提到了Java中浮点数转换为字符串时的特殊规则。...

    《Java解惑》

    2. **小数精确计算**: Java中的浮点数(如`double`)存在精度问题,如`2.00 - 1.10`并不等于预期的`0.9`。这是因为浮点数无法精确表示某些十进制小数,如`1.1`。解决方法一是使用整数表示货币,如以分表示金额,二...

    Java 解惑 (中文)

    小数精确计算 在Java中处理小数计算时,经常会遇到精度问题。这是因为不是所有的小数都能被精确表示为二进制浮点数,这导致了一些常见的误差,如`2.0 - 1.10`的结果不是预期的`0.9`,而是`0.8999999999999999`。 ...

    Java解惑 PPT1

    【Java解惑PPT1】深入探讨Java编程中的常见迷惑 在Java编程中,了解语言的细微之处至关重要,因为这可能会导致意想不到的行为。本PPT主要涵盖了五个有趣的Java谜题,帮助开发者理解Java的一些核心概念。 **谜题1:...

    JAVA解惑 中文pdf版

    ### JAVA解惑知识点详解 #### 一、表达式谜题:奇数性的判断 **谜题背景**: 在《JAVA解惑》这本书中提到了第一个谜题:如何判断一个整数是否为奇数。该谜题提供了一个看似合理的解决方案,但实际运行时会出现问题...

    经典 java 解 惑

    许多十进制小数都无法用二进制浮点数精确表示,尤其是在涉及货币金额时,这种不精确会导致计算误差累积,最终影响结果的准确性。 **解决方案:** 为了解决这个问题,可以采用以下几种方案: - 使用整数类型来存储...

    Java解惑.pdf

    ### Java解惑:深入理解Java中的谜题与陷阱 #### 表达式谜题:奇数判断误区 在探讨Java编程中的谜题时,我们首先遇到的是关于奇数判断的一个常见陷阱。根据“Java谜题”一书的中文版描述,一个简单的函数`public ...

    JAVA解惑 大量java实例 Java程序员阅读

    这种精度问题在涉及货币计算时尤其明显,因为二进制浮点数无法精确表示某些小数,如10的任何次负幂(例如0.1)。因此,虽然可以通过设置输出格式来获得看似正确的结果,例如使用`System.out.printf("%.2f%n", 2.00 -...

    JAVA解惑.doc

    ### JAVA解惑知识点详解 #### 一、表达式谜题:奇数性的判断 **谜题背景** 在《JAVA解惑》文档中的第一个谜题关注的是一个简单的逻辑判断:一个整数是否为奇数。虽然这个问题看似简单,但在Java语言中却隐藏着一个...

    Java解惑中文版(带索引)

    ### Java解惑中文版(带索引)知识点详解 #### 一、理解Java中的奇数检测方法 在Java中,判断一个整数是否为奇数是常见的编程需求。本章节介绍了一个具体的例子来探讨如何正确地实现这一功能。 **原始方法实现**:...

    java解惑 中文版

    ### Java解惑知识点详解 #### 一、表达式谜题概览 本书《Java解惑》专注于探索Java编程语言及核心类库中的复杂细节。作者通过一系列精心设计的谜题来帮助读者深入理解Java中的一些棘手问题。本书共包含了95个谜题...

Global site tag (gtag.js) - Google Analytics