[Rio-pm] Chaves de hash

thiagoglauco em ticursos.net thiagoglauco em ticursos.net
Sexta Novembro 30 04:23:54 PST 2012


Não funcionaria em 100% dos casos.

Em 2012-11-29 23:27, Blabos de Blebe escreveu:
> 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 
>>>>>>>> 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
> _______________________________________________
> 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