Pergunta

Como faço para criar ou teste para NaN ou valores infinitos em Perl?

Foi útil?

Solução 2

Aqui está uma maneira bastante confiável:

my $inf    = 9**9**9;
my $neginf = -9**9**9;
my $nan    = -sin(9**9**9);

sub isinf { $_[0]==9**9**9 || $_[0]==-9**9**9 }
sub isnan { ! defined( $_[0] <=> 9**9**9 ) }
# useful for detecting negative zero
sub signbit { substr( sprintf( '%g', $_[0] ), 0, 1 ) eq '-' }

for my $num ( $inf, $neginf, $nan ) {
   printf("%s:\tisinf: %d,\tisnan: %d,\tsignbit: %d\n", $num, isinf($num), isnan($num), signbit($num));
}

A saída é:

inf:    isinf: 1,   isnan: 0,   signbit: 0
-inf:   isinf: 1,   isnan: 0,   signbit: 1
nan:    isinf: 0,   isnan: 1,   signbit: 0

Outras dicas

print "Is NaN\n" if $a eq 'nan';
print "Is Inf\n" if $a eq 'inf' or $a eq '-inf';

Editar :. Fixo para infinito negativo

Use Data :: Float do CPAN. Ela exporta as seguintes funções:

  • float_is_infinite()
  • float_is_nan()
  • ...

E ao contrário das outras soluções meia de trabalho publicados aqui, tem um testsuite .

Pessoalmente, eu usaria Math::BigFloat (ou BigInt) para qualquer coisa que vai tocar infinidade de NaN.

Por que reinventar a roda com uma solução de corte quando já existem módulos que fazem o trabalho?

Quando eu procurei eu tenho neste site (aqui) e http://www.learning-perl.com/2015/05/perls-special-not-a-numbers/

Os pontos artigo ligado que "nan" == "nan" não é verdade, quando a implementação c subjacente suporta NaN porque Nan não pode igualar-se.

Isto é bem ilustrado com

die "This perl does not support NaN!\n" if "NaN" == "NaN";

Eu acho que o risco de executar seu código em um ambiente onde perl tem degradado graciosamente e seu código não tem pode ser baixo o suficiente para que você não se preocupar muito.

E, claro, se você não quer perl para interpolar como um número, use 'eq' não '=='

resposta sucinta que as obras seguintes.

1: Como criar uma variável "NAN" para a saída (para printf, por exemplo):

 {no strict 'subs'; $NAN="NAN"+1;}

2: Como teste para "NAN" (parecido com arte ASCII):

 sub isnan {!($_[0]<=0||$_[0]>=0)}

3: Como criar um "INF" e variáveis ??INFN:

{$INF="INF"+1; $INFN=-"INF"+1}

4: Como teste para "INF" (de qualquer sinal):

sub isinf {($_[0]==+"INF")||($_[0]==-"INF")}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top