前一段时间为了应付一些繁杂的java考试,在做一个练习时偶然发现,
用java作很简单的算术运算时,居然计算结果与实际结果有偏差;经过本人的反复测试验证,基本上可以确认,造成计算结果偏差的原因,是由java本身或java虚拟机的bug引起的。一下是完整的测试代码
package buges;import java.util.*;
public class Bugs {
    public static void main(String []args) {
        int r1=101,r2=101;
        System.out.println(r1*r2*3.14);
    }
}
相信各位用口算都可以算出来,这个结果应该是32031.14,
然而实际显示的结果却是32031.140000000003,
更奇怪的是,本人经过多次测试,发现这个错误出现有三个必须满足的条件(到目前为止,不排除还有其他的可能情况)
1、r1*r2*3.14最后结果不为整数
2、r1或r2中必须有一个是奇数,并且这个奇数的个位必须是1、3、9
3、相乘的三个数中有一个必须等于3.14满足以上两个条件后,还不一定会出这个错误,一下是本人测试的出现了错误的r1和r2的值
r1       r2
1        102
23       102
101      101或102
103      101或102
109      101或102
基本上r1如果为素数的话,就有可能出错。当然如果我们只是用于平常计算的话,这种偏差实在是太小了。但是如果计算的结果是用科学计数法来表示的话,那么这个偏差就有可能很大。如果这种偏差出现在精度要求很高的领域,那造成的损失将会很大。例如航天领域。目前本人还没有确认引起这个偏差的,到底是语言本身的缺陷,还是虚拟机的缺陷,希望各位同道一起来研究解决这个问题。

解决方案 »

  1.   

    精度问题是CPU造成的,不是java的问题,更不能说是bug了
      

  2.   

    我想 这可能涉及到结果的保留位数,尤其是内存中的位数,结果导致超出范围,调用了未知的地址
    float sum=(float)(r1*r2*3.14);
    System.out.println(sum);
    就好了
      

  3.   

    这就是为什么 判断浮点数是否相同的时候建议的不是使用==而是 用variables- 比较对象<某个精度
      

  4.   

    This is a perfectly normal and usual round-off error. It could be intorduced by not only Java, but also most medium-qualified numerical mathmatic package in most languages. More professional package, which requires more money and more computation resouce and more non-intuitive operation and more like black-box, can provide little error but it is impossible to fully eliminate the error.