Problema com subtração usando BigDecimal

Eu estou fazendo uma operação onde valor desejado = 1
e pValorObtido = 0.9999999999991193

E o resultado que estou tendo na operação:

diferencaDesejadosObtidos = diferencaDesejadosObtidos.subtract(valorObtido).setScale(MLP2.PRECISAO_VALORES,RoundingMode.HALF_UP);

é:

8.8073993E-13

O método por completo.
Ja fiz usando setScale nos dois bigdecimal, só que não resolve.
Alguem ja teve algum problema parecido?

[code] private double calculaErro(double valorDesejado, double pValorObtido){

	BigDecimal diferencaDesejadosObtidos = new BigDecimal(valorDesejado);

	BigDecimal valorObtido = new BigDecimal(pValorObtido);

	diferencaDesejadosObtidos = diferencaDesejadosObtidos.subtract(valorObtido).setScale(MLP2.PRECISAO_VALORES,RoundingMode.HALF_UP);
	
	//quadradoValorObtido = valorObtido ^ 2
	BigDecimal quadradoValorObtido = new BigDecimal(pValorObtido).pow(2).setScale(MLP2.PRECISAO_VALORES,RoundingMode.HALF_UP);
	
	//valor = 1- valorObtido ^ 2
	BigDecimal valor = new BigDecimal(1).setScale(MLP2.PRECISAO_VALORES,RoundingMode.HALF_UP);
	valor = valor.subtract(quadradoValorObtido);
	valor = valor.setScale(MLP2.PRECISAO_VALORES,RoundingMode.HALF_UP);	
	//diferencaDesejadosObtidos * valor
	BigDecimal erro = diferencaDesejadosObtidos.multiply(valor).setScale(MLP2.PRECISAO_VALORES,RoundingMode.HALF_UP);
	
	return erro.doubleValue();
}[/code]

Sendo que ja fiz essa operação usando tipos primitivos e continuo com o mesmo problema.
Eu vi um post onde o Luca falava que era limite de maquinas computacionais, mas a calculadora do windows tambem não utiliza a mesma arquitetura para fazer o calculo?Porque o Java não faz o mesmo?

Dica: experimente subtrair os dois números

new BigDecimal (“1”)

e

new BigDecimal (“0.9999999999991193”)

(olhe as aspas). Qual será o resultado?

[code]private double calculaErro(String valorDesejado,String pValorObtido){

    BigDecimal diferencaDesejadosObtidos = new BigDecimal(valorDesejado);   
  
    BigDecimal valorObtido = new BigDecimal(pValorObtido);   
  
    diferencaDesejadosObtidos = diferencaDesejadosObtidos.subtract(valorObtido).setScale(MLP.PRECISAO_VALORES,RoundingMode.HALF_UP);   
       
    //quadradoValorObtido = valorObtido ^ 2   
    BigDecimal quadradoValorObtido = new BigDecimal(pValorObtido).pow(2).setScale(MLP.PRECISAO_VALORES,RoundingMode.HALF_UP);   
       
    //valor = 1- valorObtido ^ 2   
    BigDecimal valor = new BigDecimal(1).setScale(MLP.PRECISAO_VALORES,RoundingMode.HALF_UP);   
    valor = valor.subtract(quadradoValorObtido);   
    valor = valor.setScale(MLP.PRECISAO_VALORES,RoundingMode.HALF_UP);   
    //diferencaDesejadosObtidos * valor   
    BigDecimal erro = diferencaDesejadosObtidos.multiply(valor).setScale(MLP.PRECISAO_VALORES,RoundingMode.HALF_UP);   
       
    return erro.doubleValue();   
}  [/code]

Mudando para string, obtive o seguinte resultado,thingol:

diferencaDesejadosObtidos	5.9819250E-10

Olá

Todas as linguagens e ferramentas usam as mesmas coisas para fazer contas, isto é, usam as instruções de máquina que a CPU fornece. Algumas ferramentas ou linguagens pode apresentar resultados diferentes por fazer arredondamento automático (caso do antigo Clipper e pode ser o caso da calculadora do Windows).

Aqui mesmo no GUJ já escrevi diversas vezes como devemos fazer os cálculos com números de pontos flutuantes para manter o erro sob controle. Ninguém compara números de pontos flutuantes a menos da diferença de um número muito pequeno.

eps = 1.0e-9
real1 = 2.3
real2 = 4.7
if (abs(real1-real2) < eps)
print("real1 = real2")

[]s
Luca