2014-01-27 27 views
0

我想学习一点机器人和Java。在我的尝试中,我写了一个函数(应该)采用一个名为q(0.2,0.2,0.2,0.2,0.2)的统一数组,将数组中的每个值乘以0.6或0.2,并将其与数组Z中的值相比较, (0,1,1,0,0)表示与数组世界相比数值Z的命中或遗漏,并最终返回一个新的统一阵列。Java:理解双(和规范化)

所以:通过(0,1,1,0,0) 2.) 1)循环,如果我= Z比我* 0.2,如果我= Z比我* 0.6 3.)总和!在q的双重称为规范化 4)正常化q各自值的所有新的价值(价值/正常化)

下面的功能是:

public static final double pHit = 0.6; 
    public static final double pMiss = 0.2; 
    public static int[] world = {0,1,1,0,0}; 
    public static List<Double> q = new ArrayList<Double>(); 

    public static List<Double> sense(int Z){ 
     double normalize = 0; 
     for(int i=0;i < q.size();i++){ 
      if(Z == world[i]){ 
       q.set(i, (q.get(i) * pHit)); 
      } 
      else{ 
       q.set(i, (q.get(i) * pMiss)); 
      } 
     } 
     //Normalize 
     for(int i=0;i < q.size();i++){ 
      normalize += q.get(i); 
     } 
     for(int i=0;i<q.size();i++){ 
      q.set(i, q.get(i)/normalize); 
     } 
     return q; 
    } 

如果我设置世界(0,1, 0,0,0)和Z到1我得到如下结果: 0.14285714285714288 0.4285714285714285 0.142 85714285714288 0.14285714285714288 0.14285714285714288

这很好地标准化(总和= 1)。

但如果我设置世界(0,1,1,0,0)和Z 1,我得到一个奇怪的结果: 0.1111111111111111 0.3333333333333332 0.3333333333333332 0.1111111111111111 0.1111111111111111

这种 “正常化”,以0.9999999999999998?

非常感谢您的任何意见!

回答

2

双数不是真实数字线的完美表示。他们只有大约16位数的精度。在连续的计算中,错误可以建立,有时是灾难性的。在你的情况下,这没有发生,所以要高兴。

0.1的值就是一个很好的例子。在IEEE浮点中,它只有一个近似表示。作为二元分数,其为方括号中的部分永久重复的0.0。这就是为什么浮点数(包括双打)可能不是表示价格的最佳选择。

我强烈建议阅读本经典的总结:

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

+0

不幸的是,我一遍又一遍地使用这个函数,所以它发生的只是你写的:一个灾难性的错误! :)所以,如果我理解正确,我坚持使用BigDecimal,这将大大减慢我的计算?任何人都知道python在这种情况下使用什么?我已经看到了我在python中的代码的例子,但是它并没有说明他们甚至使用了什么样的变量...... – user2826751

+1

你真的需要更精确的结果吗? BigDecimal有同样的问题。三分之一不能完全代表它。 –

+1

@ user2826751没有任何浮点表示将永远是完美的。为什么地球上有一个0.0000000000000001正常化的错误? – Gene

0

浮点数在计算机上没有完全表示。出于这个原因,当将浮点值相乘时,您会从精确值中得到非常小的分数。

请参阅this answer,因为它更深入地讨论了浮动表示,并引用了这篇Floating-Point Arithmetic文章。

0

欢迎浮点数的世界! 我没有试图详细了解你的代码,但结果0.9999999999999998是完全正常的。我建议你阅读一下关于floating point numbers和他们的精确度。