[Rio-pm] Chaves de hash

Blabos de Blebe blabos em gmail.com
Quinta Novembro 29 17:27:58 PST 2012


Um exemplo hipotético...

Suponha que não haja escapatória e tenha-se que comparar flutuantes...

if ( float_equal( $a, $b ) ) {
    say 'igual';
}
elsif ( $a < $b && !float_equal( $a, $b ) ) {
    say 'menor';
}
else {
    say 'maior';
}

Será que funciona?

2012/11/29  <thiagoglauco em ticursos.net>:
> Um exemplo mais preciso:
>
> $ uname -a
> SunOS cg01spo 5.10 Generic_138888-03 sun4v sparc SUNW,SPARC-Enterprise-T5120
>
> $ perl -E '
> if (0.2 > 0.19999999999999997){
> say "0.2 is greater than 0.19999999999999997";}
>
> else {
> say "Floating Point is not true real"};'
> 0.2 is greater than 0.19999999999999997
> $
>
> $ perl -E '
> if (0.2 > 0.19999999999999998){
> say "0.2 is greater than 0.19999999999999998";}
>
> else {
> say "Floating Point is not true real"};'
> Floating Point is not true real
> $
>
> Por que é importante saber essas coisas?
> http://ta.twi.tudelft.nl/users/vuik/wi211/disasters.html
>
>
>
>
>
>
> Em 2012-11-29 15:13, thiagoglauco em ticursos.net escreveu:
>
>>> 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
>>
>>
>> _______________________________________________
>> 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