zoukankan      html  css  js  c++  java
  • Java中的二进制运算出错问题

    问题:

    最近在做Java web项目中需要计算金额总和,在这里出现了一个问题是我以前没有关注到的:

    System.out.println(2.0-1.1);

    执行时候的console中打印输出的是

    0.8999999999999999

    而不是正常计算出2.0-1.1=0.9这个答案,

    原因:

    对此我找了一些解答,主要是二进制机器在处理十分之一(0.1)上出现的问题。

    主要问题出在小数的二进制表示上

    这里参考了这篇博客所讲的:http://hxraid.iteye.com/blog/504293

    (1)  十进制整数如何转化为二进制数

               算法很简单。举个例子,11表示成二进制数:

                         11/2=5   余   1

                           5/2=2   余   1

                           2/2=1   余   0

                           1/2=0   余   1

                              0结束         11二进制表示为(从下往上):1011

              这里提一点:只要遇到除以后的结果为0了就结束了,所有的整数除以2是不是一定能够最终得到0。换句话说,所有的整数转变为二进制数的算法会不会无限循环下去呢?绝对不会,整数永远可以用二进制精确表示 ,但小数就不一定了。

     (2) 十进制小数如何转化为二进制数

               算法是乘以2直到没有了小数为止。举个例子,0.9表示成二进制数

                         0.9*2=1.8   取整数部分  1

                         0.8(1.8的小数部分)*2=1.6    取整数部分  1

                         0.6*2=1.2   取整数部分  1

                         0.2*2=0.4   取整数部分  0

                         0.4*2=0.8   取整数部分  0

                         0.8*2=1.6   取整数部分  1

                         0.6*2=1.2   取整数部分  0

                                  .........      0.9二进制表示为(从上往下): 1100100100100......

               注意:上面的计算过程循环了,也就是说*2永远不可能消灭小数部分,这样算法将无限下去。很显然,小数的二进制表示有时是不可能精确的 。其实道理很简单,十进制系统中能不能准确表示出1/3呢?同样二进制系统也无法准确表示1/10。

    这也就解释了这个问题出现的原因。

    解决:

    知道原因之后我们应该怎么做呢?其实可以用Java中提供的

    BigDecimal实现精确加减乘除运算

    BigDecimal提供的BigDecimal(String val)构造方法,使用BigDecimal要用String来够造,要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。

    加减乘除操作:

    public BigDecimal add(BigDecimal value);
    public BigDecimal subtract(BigDecimal value);
    public BigDecimal multiply(BigDecimal value);
    public BigDecimal divide(BigDecimal value);

    在计算完之后,利用doubleValue()方法将BigDecimal转换成Double类型就可以避免上述的错误了。

  • 相关阅读:
    Web网页数据抽取软件的设计与实现
    以Groovy的方式更稳定地解析HTML(转载)
    HTML 资讯汲取(上篇) 使用 JDOM 、 TagSoup 及 XPath
    html解析
    HTML 資訊汲取(下篇) TagSoup 輸出 namespace 問題的解決方案
    国外免费主机空间
    ASP.NET获取客户端IP地址、系统版本、浏览器版本
    阁下莫非就是当年华山论剑武功独步天下罕有其匹号称一朵梨花压海棠的少林寺智障大师收养的小沙弥低能的爱犬旺财踩扁的蟑螂小强曾滚过的一个粪球?
    html中table里的col标签
    Visual Studio 2010 中的 TODO
  • 原文地址:https://www.cnblogs.com/winterfells/p/8595595.html
Copyright © 2011-2022 走看看