关于数据精度的问题

    昨天和朋友聊到数据精度的问题,颇有感慨。
    首先是《Java Puzzle》一书上的一个例子:如果采用double或者float类型的数据定义,在进行简单运算的时候,可能出现精度上的错误。比如:
  1. System.out.println(2.001.10);
    输出的结果将是0.89999999999999,而不是我们理论上的0.9。为什么呢?因为“并不是所有的小数都可以用二进制浮点数精确表示”——0.1就是一个例子。不妨用“乘二算法”计算一下0.1的二进制表示,你会得到一个无限循环的序列。
    该书给出的结论是:在需要精确答案的地方,要避免使用float和double;对于货币计算,要使用int、long或BigDecimal。

    我心中一动:C++里面又会如何呢?难道我以前一直在忽略这个问题吗?为什么从来没有注意过这种现象,也没有在《Effective C++》这类高级进阶书籍上遇到过类似情况的介绍呢?
    随便写个测试程序:
  1. double i=2.0;double j=1.1;
  2. cout<<i-j<<endl;
    在Ubuntu8.04、G++环境下编译运行,结果:0.9。我记得在以前ACM编程的时候,也有人建议过:尽量用double,不用float。我还有印象的是:在C++中使用float,也可能导致精度的问题。
    另外,再测试一下另一个可能产生精度问题的程序:
  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. double i=1.0;double j=3.0;double q;
  6. q=i/j;
  7. cout<<q<<endl;
  8. cout<<q*3.0<<endl;
  9. return 0;
  10. }
    如果精度会有问题的话,q输出0.33333333,那么q*3.0就会输出0.99999999(非精确)。不过C++没有让我失望:它输出1.0;而且在windows自带的计算器中,对于精度的把握,相当的到位。我记得曾经进行过一个巨大数值的计算(超越double类型的上限),然后乘、除......最后逆向算回来,没有发现精度的损失;当时小小地惊叹了一把。

你可能感兴趣的:(关于数据精度的问题)