Quando comparamos valores inteiros podemos usar o operador relacional ==
. Quando comparamos valores com parte decimal (double
ou float
) temos que ter cuidado pois, devido ao número limitado de algarismos significativos nestes tipos, pequeníssimos erros podem ser introduzidos que fazem com que a comparação não produza o efeito desejado.
Estes erros podem ser introduzidos não só na representação dos números em decimais vírgula flutuante, mas também nos cálculos que vamos fazendo ao longo do programa.
O operador ==
só resulta num valor true quando os valores comparados são exatamente iguais. A execução do seguinte pedaço de código escreveria diferentes! no ecrã:
xdouble x = 10.1;
double y = x - 7; // y fica igual a 3.1
double w = x / y; // divide x por 3.1
w = w * 3.1; // multiplica w por 3.1 -- ficaria igual a 10.1
if (w == 10.1){
System.out.println("iguais!");
} else {
System.out.println("diferentes!");
}
E a execução da instrução
System.out.println("x = " + x + " w = " + w);
escreveria x = 10.1 w = 10.100000000000001 no ecrã:
Devemos então comparar números com parte decimal de forma não exata, ou seja, definindo uma tolerância máxima até à qual é aceitável considerar que os números são iguais:
Se chamarmos delta
à tolerância, então a condição w > x – delta && w < x + delta
define os valores w
que consideramos iguais a x
.
Esta condição é equivalente a esta outra w - x > –delta && w - x < delta
que é exatamente a que resulta de desdobrar o módulo |w – x| < delta
.
O seguinte método permite decidir se dois números com parte decimal são iguais a menos de uma tolerância delta
.
xxxxxxxxxx
/**
* Dois numeros sao iguais a menos de uma dada tolerancia?
* @param x1
* @param x2
* @param delta A tolerancia
* @return true se a diferenca entre x1 e x2 eh menor que delta;
* false caso contrario
*/
static boolean iguais(double x1, double x2, double delta) {
return Math.abs(x1 – x2) < delta;
}
A execução das instruções seguintes, por exemplo, inseridas no método main
da classe contendo o método iguais
, escreveria iguais! no ecrã.
xxxxxxxxxx
double x = 10.1;
double y = x - 7; // y fica igual a 3.1
double w = x / y; // divide x por 3.1
w = w * 3.1; // multiplica w por 3.1
if (iguais(w, 10.1, 0.0001){
System.out.println("iguais!");
} else {
System.out.println("diferentes!");
}
Aqui aceitámos considerar que os valores são iguais desde que a sua diferença, em valor absoluto, seja menor que 0.0001.
Sempre que queremos comparar valores numéricos não inteiros devemos fazê-lo desta maneira.
Se inspecionássemos a memória durante a execução deste programa, observaríamos este estado imediatamente antes de a chamada à função iguais
terminar:
Podemos constatar, através do conteúdo das variáveis, que a representação dos valores no tipo double
não é necessariamente exata, devido ao número de algarismos significativos ser limitado.
Anterior: 5.3. Ainda a documentação
Seguinte: 6. Ciclos