我正在尝试学习一些机器人技术和 Java 知识。在我的尝试中,我编写了一个函数,该函数(应该)采用名为 q(0.2,0.2,0.2,0.2,0.2) 的统一数组,与另一个数组世界相比,根据值 Z 将该数组中的每个值乘以 0.6 或 0.2 (0,1,1,0,0) 表示与数组世界相比 Z 值的命中或未命中,最终返回一个新的统一数组。
所以: 1.) 循环 (0,1,1,0,0) 2.) 如果 i!=Z 比 i*0.2,如果 i=Z 比 i*0.6 3.) 将 q 中的所有新值求和为称为标准化的 double 值 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;
}
如果我将 world 设置为 (0,1,0,0,0) 并将 Z 设置为 1,我会得到以下结果: 0.14285714285714288 0.4285714285714285 0.14285714285714288 0.14285714285714288 0.14285714285714288
这很好地标准化(总和 = 1)。
但是如果我将 world 设置为 (0,1,1,0,0) 并将 Z 设置为 1,我会得到一个奇怪的结果: 0.1111111111111111 0.3333333333333332 0.3333333333333332 0.1111111111111111 0.1111111111111111
这“标准化”为 0.9999999999999998 ?
非常感谢您的任何意见!
最佳答案
double 并不是实数轴的完美表示。它们的精度只有大约 16 位。在连续的计算中,可能会产生错误,有时甚至是灾难性的。就你而言,这还没有发生,所以高兴吧。
值 0.1 是一个很好的例子。在 IEEE 浮点中,它只有近似表示。作为二进制分数,它是 0.0[0011],其中方括号中的部分永远重复。这就是为什么 float (包括 double )可能不是表示价格的最佳选择。
我强烈建议阅读这篇经典摘要:
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
关于Java:理解 double (和规范化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21387688/