[Rio-pm] Chaves de hash

thiagoglauco em ticursos.net thiagoglauco em ticursos.net
Quinta Novembro 29 09:13:12 PST 2012


> Não se compara reais por igualdade.
Se você tem erro na igualdade, terá nas outras comparações se a 
diferença entre os números for menor que o maior acréscimo suportado 
pela plataforma:

$ perl -E '
if (0.2 > 0.19999999999999999999999999999999999999999999){
> say "0.2 is greater than 0.19999999999999999999999999999999999999";}
> else {
> say "Floating Point is not true real"};'
Floating Point is not true real
$

$ perl -E '
if (0.2 > 0.199999){
say "0.2 is greater than 0.199999";}
else {
say "Floating Point is not true real"};'
0.2 is greater than 0.199999
$

Então, comparar pontos flutuantes não é seguro. Nem igualdade, nem 
maio, nem menor.

E mais: garanto que se você quer usar um número real como chave de Hash 
você tem um problema na análise da lógica do problema que está 
enfrentando e como solucioná-lo.


Em 2012-11-29 10:36, Blabos de Blebe escreveu:
> Na verdade é o contrário, não?
>
> Não se compara reais por igualdade.
>
> Se você usa reais como chaves de hash, você tem algum problema...
>
> Ao não controlar a representação interna em ponto flutuante, você 
> pode
> nunca mais alcançar o valor relacionado à chave, se usar um número
> real como chave, pois qualquer bit diferente, mesmo que arredondando
> no mesmo número vai resultar num cálculo diferente na tabela hash.
>
> Igualdade entre númros reais constuma ser definida como algo assim:
>
> sub float_equal {
>     my ($first, $second) = @_;
>     my $threshold = 0.00000001 # arbitrário
>     return abs( $first - $second ) < $threshold;
> }
>
> Converter para string antes de usar como chave de hash também não me
> parece saudável, pois, embora a string vá funcionar bem no hash, você
> não garante que a conversão vai resultar sempre na mesma string, e aí
> vc se ferra do mesmo jeito.
>
> Por outro lado, se você nunca vai acessar o elemento do hash através
> da chave, um foreach por keys() ou values() vai te retornar os
> valores...
>
> Mas aí eu te perguntaria por que rails você está usando hash pra 
> isso...
>
>
>
> On Thu, Nov 29, 2012 at 6:47 AM,  <thiagoglauco em ticursos.net> wrote:
>> Existe um problema aqui, diferente da comparação.
>> A comparação de reais é problemática devido a estrutura interna do 
>> ponto
>> flutuante. NÃO SE COMPARA REAIS POR MAIOR OU MENOR.Isso não é do 
>> Perl, mas
>> das regras de aproximação usada pelos processadores.
>>
>> Rounding rules
>>
>> The standard defines five rounding rules. The first two round to a 
>> nearest
>> value; the others are called directed roundings:
>> Roundings to nearest
>>
>>     Round to nearest, ties to even – rounds to the nearest value; if 
>> the
>> number falls midway it is rounded to the nearest value with an even 
>> (zero)
>> least significant bit, which occurs 50% of the time; this is the 
>> default for
>> binary floating-point and the recommended default for decimal.
>>     Round to nearest, ties away from zero – rounds to the nearest 
>> value; if
>> the number falls midway it is rounded to the nearest value above 
>> (for
>> positive numbers) or below (for negative numbers); this is intended 
>> as an
>> option for decimal floating point.
>>
>> Directed roundings
>>
>>     Round toward 0 – directed rounding towards zero (also known as
>> truncation).
>>     Round toward +∞ – directed rounding towards positive infinity 
>> (also
>> known as rounding up or ceiling).
>>     Round toward −∞ – directed rounding towards negative infinity 
>> (also
>> known as rounding down or floor).
>>
>> Se a comparação for inevitável, converta o seu número para string e 
>> compare
>> ou determine um nível de precisão aceitável e faça bit a bit.
>>
>> Em 2012-11-28 21:42, Aureliano Guedes escreveu:
>>>
>>> Ola Monges.
>>>
>>> Estou com um problema simples mas que não acho a solução.
>>>
>>> Eu tenho um hash onde as chaves são valores numericos reais (a
>>> maioria negativo e quase nenhum inteiro).
>>> Estou limitando esses valores por um maximo e um minimo.
>>>
>>>  foreach my $keys (keys %d) {
>>>  if ($keys <= $min and $keys >= $max) {
>>>  print "$d{$keys}";
>>>  }
>>>  }
>>>
>>> Problema que não da certo.
>>> Ha algo de errado aqui??
>>>
>>> _______________________________________________
>>> Rio-pm mailing list
>>> Rio-pm em pm.org
>>> http://mail.pm.org/mailman/listinfo/rio-pm
>>
>>
>> _______________________________________________
>> Rio-pm mailing list
>> Rio-pm em pm.org
>> http://mail.pm.org/mailman/listinfo/rio-pm
> _______________________________________________
> Rio-pm mailing list
> Rio-pm em pm.org
> http://mail.pm.org/mailman/listinfo/rio-pm



Mais detalhes sobre a lista de discussão Rio-pm