Ao comparar carros alegóricos, como você chama o limiar da diferença?


10

Agora estou comparando carros alegóricos em Java e a fórmula mais simples é:

Math.abs(a - b) < THRESHOLD

Ao nomear sua variável para o limiar da diferença, você deve nomear delta ou epsilon ? Especificamente, qual dos dois é o termo correto para o menor valor que um número de ponto flutuante pode representar?

O termo linguagem de programação é específico ou é universal entre as línguas?


1
Termos alternativos: "precisão", "resolução". Gosto disso precisamente;) porque eles não parecem muito técnicos.
stakx

1
Fora do tópico: o Guia de ponto flutuante recomenda não usar esse tipo de comparação de quase igualdade.
stakx

1
@stakx - os termos sugeridos estão incorretos e têm significados diferentes do que o OP está perguntando. A questão é detalhada, sim, mas é responsável com base em referência externa e tem relevância para a programação ao lidar com valores de ponto flutuante. É construtivo e temático.

1
@ GlenH7: Eu nunca disse que a pergunta não era boa ou não respondia. Na verdade, eu fui quem votou melhor. E como você está afirmando que os termos (reconhecidamente menos precisos) que sugeri estão incorretos, eu estaria interessado em saber por que isso acontece.
stakx

@stakx - desculpas por sugerir que você votou para fechar. Eu estava reagindo mais às quatro votações mais próximas sobre a questão no momento.

Respostas:


18

Epsilon em matemática e engenharia

Em matemática e engenharia em geral:

  • Delta é geralmente usado para se referir a uma diferença, que pode ser de qualquer escala.
  • Epsilon é geralmente usado para se referir a uma quantidade desprezível.

e epsilon parece mais apropriado no seu caso.


Epsilon em ciência da computação

Em ciência da computação, em particular, o termo epsilon também se refere a máquina espilon, que mede a diferença entre 1.0fe o menor flutuador que é estritamente maior que 1.0f. Esse último número é 1.00000011920928955078125fpara carros alegóricos em Java e pode ser calculado com:

float f = Float.intBitsToFloat(Float.floatToIntBits(1f) + 1);

A definição de máquina epsilon é consistente com o uso geral do epsilon descrito acima.


Comparando carros alegóricos

Observe, no entanto, que, antes de comparar as flutuações para "proximidade", você precisa ter uma idéia da escala delas. Dois flutuadores muito grandes e supostamente muito diferentes podem ser iguais:

9223372036854775808f == 9223372036854775808f + 1000000000f; //this is true!

E, inversamente, pode haver muitos valores possíveis de flutuação (e várias ordens de grandeza) entre duas pequenas flutuações que diferem pelo epsilon da máquina "apenas". No exemplo abaixo, existem 10.000.000 valores de flutuação disponíveis entre smalle f, mas sua diferença ainda está bem abaixo do epsilon da máquina:

float small = Float.MIN_VALUE; // small = 1.4E-45
float f = Float.intBitsToFloat(Float.floatToIntBits(small) + 100000000); // f = 2.3122343E-35
boolean b = (f - small < 0.00000011920928955078125f); //true!

O artigo vinculado na resposta da GlenH7 investiga ainda mais a comparação de flutuadores e propõe várias soluções para superar esses problemas.


2
-1: no software científico computacional, Epsilon refere-se ao Machine epsilon ou relativo epsilon (consulte o mesmo artigo). Normalmente, essa não é a mesma quantidade usada na aceitação da igualdade aproximada, porque os erros de arredondamento são múltiplos de epsilons de máquina ou epsilons relativos e geralmente têm uma ordem de magnitudes maior que isso.
rwong 8/08/13

1
@rwong Essa é uma especialização do termo epsilon , e existem muitas outras. Na engenharia em geral, o epsilon se refere a uma pequena quantidade ou erro e o Machine epsilon é compatível com essa ideia.
assylias

@assylias, usando um nome que tem uma definição padrão, em um contexto em que a definição padrão faz sentido, mas para algo que não corresponde à definição padrão é um recibo para problemas.
APROGRAMMERJ #

@ AProgrammer Não concordo que a definição geral de epsilon não seja aplicável à computação.
assylias

1
@assylias: obrigado pelo esclarecimento. Eu removi meu -1.
precisa saber é o seguinte

16

Em matemática, delta é usado para representar alguma diferença em relação a um valor, epsilon é usado para representar um valor de erro arbitrário. Nesse caso, epsilon seria o nome convencional.


8

Para responder diretamente sua pergunta, você quer usar o termo epsilon. Mais precisamente, é machine epsilonmas o uso comum descarta "máquina" e apenas usa epsilon.

Olhando em minha cópia local, float.hvejo:

#define DBL_EPSILON     2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */  
#define FLT_EPSILON     1.192092896e-07F        /* smallest such that 1.0+FLT_EPSILON != 1.0 */  
#define LDBL_EPSILON    DBL_EPSILON             /* smallest such that 1.0+LDBL_EPSILON != 1.0 */

E os comentários associados deixam claro que épsilon é o termo a que você está se referindo.

Mas também podemos confiar em outras referências externas para verificar se esse epsiloné o termo correto. Veja aqui , aqui , aqui e, finalmente, essa combinação de tags de consulta SO . Não consegui encontrar uma referência direta ao padrão IEEE 754 para citar.


Você não perguntou, mas achei esta referência muito relevante para o exemplo que você forneceu para esclarecer sua pergunta.

Dê uma olhada neste artigo de blog de Bruce Dawson, da Valve, sobre a comparação de valores de ponto flutuante para obter algumas dicas sobre por que você não deseja usar a comparação sugerida.

Há bastante informação nesse artigo, mas este é o snipppet mais relevante de lá:

Se comparar floats por igualdade é uma péssima idéia, que tal verificar se a diferença está dentro de alguns limites de erro ou no valor epsilon, assim:

bool isEqual = fabs(f1 – f2) <= epsilon;

Com esse cálculo, podemos expressar o conceito de dois carros alegóricos estando próximos o suficiente para que possamos considerá-los iguais. Mas que valor devemos usar para o epsilon?
Dada a nossa experimentação acima, podemos ficar tentados a usar o erro em nossa soma, que era de 1,19e-7f. De fato, existe até uma definição em float.h com esse valor exato, e é chamada FLT_EPSILON.
Claramente é isso. Os deuses do arquivo de cabeçalho falaram e FLT_EPSILON é o único epsilon de verdade!
Exceto que isso é lixo. Para números entre 1,0 e 2,0, FLT_EPSILON representa a diferença entre flutuadores adjacentes. Para números menores que 1,0, um epsilon de FLT_EPSILON rapidamente se torna muito grande e, com números pequenos o suficiente, FLT_EPSILON pode ser maior que os números que você está comparando!

Dawson aborda várias outras considerações sobre os meandros envolvidos na comparação de carros alegóricos e no tratamento de valores muito pequenos como esse, portanto, incentivaria sua leitura no restante do post.


Você pode esclarecer a primeira parte de sua resposta: o artigo de Bruce já explica por que não se deve usar um epsilon constante (como os definidos em um arquivo de cabeçalho) para comparação de tolerância. Além disso, em muitos casos, um erro de alguns milhões de ULPs não é motivo de preocupação, porque na maioria dos aplicativos, nos preocupamos mais com os dígitos significativos do que com os erros dos dígitos menos significativos, porque a precisão dupla já fornece muito mais dígitos do que nos preocupamos.
rwong

@ rwong - como eu o li, a questão era identificar o termo correto a ser usado no nome de uma constante. É por isso que forneci a referência float.h juntamente com algumas outras para usinar o epsilon. O artigo de Dawson é algo que eu encontrei ao pesquisar a referência IEEE 754 e achei relevante para os OPs simplest formulapara comparação. Muitos usam essa abordagem como primeira tentativa, e eu incluí o artigo de Dawson, porque ele realmente entra nas nuances de quão complicada é a comparação. Então, tentei responder diretamente à pergunta e apontei por que não usá-la dessa maneira.

5

Esta é uma função de erro; erro absoluto é geralmente chamado ε (epsilon) ou Δ x para alguma quantidade x:

ε = | esperado - real |

Δ x = | x 0 - x  |

Às vezes, o erro relativo é chamado η (eta):

η = | 1 - real / esperado |

Para fins de programação, absoluteErrore relativeError(ou algumas abreviações) são mais descritivos. Se você deseja afirmar que o erro é menor que um determinado valor, esse valor seria simplesmente chamado de limite ou tolerância .

Vejo:


3

Eu chamaria isso de "tolerância".

Talvez esse não seja o termo matematicamente correto, mas o simples fato de você fazer a pergunta implica para mim que nem "delta" nem "epsilon" seriam um bom nome de variável a ser usado.

Na minha experiência, é melhor usar nomes de identificadores que façam sentido para quem realmente lerá o código. De que vale um nome perfeitamente correto se significa que o leitor precisa procurá-lo na Wikipedia para entender o que significa?


+1. Eu sempre espero que as pessoas perguntem a seus colegas sobre essas questões de nomenclatura, além de postarem aqui.
MarkJ

6
-1, é melhor aprender convenções do que evitá-las.
djechlin

+1 porque esta é exatamente a mesma razão pela qual eu postei esta pergunta.
NobleUplift 8/08
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.