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, thiagogla...@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, <thiagogla...@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@pm.org
http://mail.pm.org/mailman/listinfo/rio-pm
_______________________________________________
Rio-pm mailing list
Rio-pm@pm.org
http://mail.pm.org/mailman/listinfo/rio-pm
_______________________________________________
Rio-pm mailing list
Rio-pm@pm.org
http://mail.pm.org/mailman/listinfo/rio-pm
_______________________________________________
Rio-pm mailing list
Rio-pm@pm.org
http://mail.pm.org/mailman/listinfo/rio-pm
_______________________________________________
Rio-pm mailing list
Rio-pm@pm.org
http://mail.pm.org/mailman/listinfo/rio-pm