Qual é o valor da expressão algébrica? - Brainly.com.br


187

Eu tenho uma pergunta sobre junit assertEqualspara testar valores duplos. Lendo o documento da API, posso ver:

@Deprecated
public static void assertEquals(double expected, double actual)

Descontinuada. Use assertEquals (dobro esperado, dobro real, dobro epsilon)

O que o epsilonvalor significa? (Epsilon é uma letra do alfabeto grego, certo?).

Alguém pode me explicar como usá-lo?

Respostas:


198

Epsilon é o valor pelo qual os 2 números podem ser desativados. Por isso, afirmará verdadeiro, desde queMath.abs(expected - actual) < epsilon


3
Então, qual valor devo passar como epsilon?
Emeraldhieu

15
@ Emerald214 a quantidade de precisão. Se você deseja afirmar que um valor duplo é 0D, o epsilon seria 0 (100% de precisão, sem exceções). Se você deseja uma margem de erro (digamos em graus), pode definir o epsilon como 1, o que significa, por exemplo, 64,2 ° é o mesmo que 64,8 ° (uma vez que abs (64,8-64,2) <1)
Pieter De Bie,

3
A documentação diz: "delta - o delta máximo entre o esperado e o real para o qual os dois números ainda são considerados iguais". Então eu acho que deveria ser um <=não <.
Andrew Cheong

Observando o código, vejo que ele chama o método doubleIsDifferent(para comparar valores duplos) e retorna Math.abs(d1 - d2) > delta. Portanto, se a diferença entre d1 e d2 for maior que delta, isso significa que os valores são diferentes e retornarão true. Retornará false se os valores forem considerados iguais. Esse método é chamado diretamente no assertEquals e, se retornar verdadeiro, o assertEquals chamará failNotEqualse o resultado do teste será uma falha.
Anthomaxcool #

1
@ jbert Alguém pode aconselhar qual seria o valor duplo típico do epsilon se eu estivesse trabalhando com uma média de muitos números ou fazendo desvios padrão?
simgineer 23/03/19

121

Qual versão do JUnit é essa? Eu só vi delta, não epsilon - mas isso é uma questão secundária!

No javadoc JUnit :

delta - o delta máximo entre o esperado e o real para o qual os dois números ainda são considerados iguais.

Provavelmente é um exagero, mas normalmente uso um número muito pequeno, por exemplo

private static final double DELTA = 1e-15;

@Test
public void testDelta(){
    assertEquals(123.456, 123.456, DELTA);
}

Se você estiver usando declarações de hamcrest , poderá usar o padrão equalTo()com duas duplas (ele não usa um delta). No entanto, se você quiser um delta, basta usar closeTo()(consulte javadoc ), por exemplo

private static final double DELTA = 1e-15;

@Test
public void testDelta(){
    assertThat(123.456, equalTo(123.456));
    assertThat(123.456, closeTo(123.456, DELTA));
}

Para sua informação, o próximo JUnit 5 também tornará o delta opcional ao pagar assertEquals()com duas duplas. A implementação (se você estiver interessado) é:

private static boolean doublesAreEqual(double value1, double value2) {
    return Double.doubleToLongBits(value1) == Double.doubleToLongBits(value2);
}

57

Os cálculos de ponto flutuante não são exatos - geralmente há erros de arredondamento e erros devido à representação. (Por exemplo, 0.1 não pode ser representado exatamente no ponto flutuante binário.)

Por isso, comparar diretamente dois valores de ponto flutuante para igualdade geralmente não é uma boa ideia, pois eles podem ser diferentes em uma pequena quantidade, dependendo de como foram calculados.

O "delta", como é chamado nos javadocs da JUnit , descreve a quantidade de diferença que você pode tolerar nos valores para que eles ainda sejam considerados iguais. O tamanho desse valor depende inteiramente dos valores que você está comparando. Ao comparar duplas, normalmente uso o valor esperado dividido por 10 ^ 6.


11

O fato é que dois duplos podem não ser exatamente iguais devido a problemas de precisão inerentes aos números de ponto flutuante. Com esse valor delta, você pode controlar a avaliação da igualdade com base em um fator de erro.

Além disso, alguns valores de ponto flutuante podem ter valores especiais, como NAN e -Infinity / + Infinity, que podem influenciar os resultados.

Se você realmente pretende comparar que duas duplas são exatamente iguais, é melhor compará-las como uma representação longa

Assert.assertEquals(Double.doubleToLongBits(expected), Double.doubleToLongBits(result));

Ou

Assert.assertEquals(0, Double.compareTo(expected, result));

O que pode levar essas nuances em consideração.

Não mergulhei no método Assert em questão, mas só posso supor que o anterior foi descontinuado para esse tipo de problema e o novo leva-os em consideração.


2

Epsilon é uma diferença entre expectede actualvalores que você pode aceitar pensando que são iguais. Você pode definir, .1por exemplo.


2

Observe que, se você não estiver fazendo matemática, não há nada errado em afirmar valores exatos de ponto flutuante. Por exemplo:

public interface Foo {
    double getDefaultValue();
}

public class FooImpl implements Foo {
    public double getDefaultValue() { return Double.MIN_VALUE; }
}

Nesse caso, você quer ter certeza de que não é realmente MIN_VALUEzero -MIN_VALUEou MIN_NORMALou algum outro valor muito pequeno. Você pode dizer

double defaultValue = new FooImpl().getDefaultValue();
assertEquals(Double.MIN_VALUE, defaultValue);

mas isso receberá um aviso de descontinuação. Para evitar isso, você pode ligar assertEquals(Object, Object):

// really you just need one cast because of autoboxing, but let's be clear
assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue);

E, se você realmente quer parecer inteligente:

assertEquals(
    Double.doubleToLongBits(Double.MIN_VALUE), 
    Double.doubleToLongBits(defaultValue)
);

Ou você pode simplesmente usar afirmações no estilo fluente de Hamcrest:

// equivalent to assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue);
assertThat(defaultValue, is(Double.MIN_VALUE));

Se o valor que você está verificando for proveniente de algumas contas, use o epsilon.


7
Se você deseja verificar se há exatamente iguais, defina epsilon como 0,0 - a variante Objeto não é necessária.
Mel Nicholson

-2
Assert.assertTrue(Math.abs(actual-expected) == 0)

Ao usar números de ponto flutuante (como flutuante ou duplo), isso não funcionará de maneira confiável. Você pode revisar como os números de ponto flutuante em java são armazenados e como as operações aritméticas funcionam neles. (spoiler: espere alguns erros de arredondamento!)
Attila
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.