So, basically I have this algorithm that codes a word using arithmetic coding. The matrix with the percentages(String[][] tabelaProbs and the word (String palavra) are the following :
Matrix:
String tabelaProbs[][] = {{"A", "E", "I", "O", "U", "!"},{"0.2", "0.3", "0.1", "0.2", "0.1", "0.1"}};
Word:
String palavra = "EAII!"; (in lower case: " e a i i ! ")
The thing is, it's giving me the wrong result because some of sums with the doubles are giving the wrong result and that's affecting the final result aswell. The final result ( credencialCodificada ) is expected to be : 0.23354
Can anyone help?
public static double codificarCredenciaisAcesso(String[][] tabelaProbs, String palavra) {
double aux = 0;
String letra, palavraAux = "";
int indice = 0;
double[] probabilidadesAux = new double[tabelaProbs[1].length + 2];
probabilidadesAux[0] = 0;
for (int i = 0; i < tabelaProbs[1].length; i++) {
aux += Double.parseDouble(tabelaProbs[1][i].trim());
probabilidadesAux[i + 1] = aux;
}
probabilidadesAux[probabilidadesAux.length - 1] = 1;
for (int indiceLetra = 0; indiceLetra < palavra.length(); indiceLetra++) {
letra = palavra.charAt(indiceLetra) + "";
palavraAux += letra;
for (int iProb = 0; iProb < tabelaProbs[0].length; iProb++) {
if (letra.equalsIgnoreCase(tabelaProbs[0][iProb])) {
indice = iProb;
break;
}
}
double intervaloProb = probabilidadesAux[indice + 1] - probabilidadesAux[indice];
for (int i = 0; i < probabilidadesAux.length; i++) {
if (indice == i) {
probabilidadesAux[0] = probabilidadesAux[indice];
probabilidadesAux[probabilidadesAux.length - 1] = probabilidadesAux[indice + 1];
aux = probabilidadesAux[0];
for (int j = 1; j < probabilidadesAux.length - 1; j++) {
double probabilidadeX = Double.parseDouble(tabelaProbs[1][j - 1]);
probabilidadesAux[j] = aux + (probabilidadeX * intervaloProb);
aux = probabilidadesAux[j];
}
break;
}
}
}
double credencialCodificada = probabilidadesAux[indice];
return credencialCodificada;
}
The problem is that doubles have accuracy less than their total size. So 3.0000004 is accurate to 4 decimal points, but it is longer than 4 decimal points.
This is also why you should avoid comparing or grouping by doubles.
Here is a link talking about something like that : how to fix double precision issue in java