2009-07-26 12 views

risposta

12

Ecco un modo abbastanza affidabile:

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)); 
} 

uscita è:

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

Su 5,10 e al di sopra, dove la libreria C supporta, basta 0+ "nan" , 0+ "inf", o 0 + "- inf" funzionano anche. – ysth

+1

Molto energico da parte tua: 13 minuti fa, fai la domanda; 11 minuti fa, rispondi; 9 minuti fa, si pubblica un commento. Dovresti comprarti una birra o qualcosa del genere. – Telemachus

+0

@Telemachus: Tranne che non bevo roba ... – ysth

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

EDIT: fisso per infinito negativo.

+0

Chi ha votato per votare, lascia che lasci la posta se non ti vergogni. In questo modo funziona assolutamente perfetto in perl. Se $ a è il numero, la rappresentazione della stringa sarà 'nan' o 'inf' solo se è NaN o Inf. –

+0

Cosa succede se $ a non è un numero, ma in realtà è la stringa "nan"? –

+0

@Ryan: String "nan" non è un numero certo. la soluzione di ysth funziona esattamente allo stesso modo. Controlla 'perl -le 'sub isnan {! definito ($ _ [0] <=> 9 ** 9 ** 9)}; print isnan ("nan") ''se non ti fidi di me. –

4

Personalmente, vorrei utilizzare Math::BigFloat (o BigInt) per tutto ciò che sta per toccare infinito di NaN.

Perché reinventare la ruota con una soluzione di hack quando ci sono già moduli che fanno il lavoro?

-3

Risposta succinta che segue.

1: Come creare una variabile "nan" per l'uscita (a printf, per esempio):

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

2: Come testare per "nan" (sembra ascii art):

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

3: Come creare un "INF" e variabili INFN:

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

4: Come testare per "INF" (di qualsiasi segno):

sub isinf {($_[0]==+"INF")||($_[0]==-"INF")} 
+1

(1) e (3) non sono diversi da solo '$ NAN =" NAN "+1;', '$ INF =" INF "+1; $ INFN = - "INF"; 'solo più verboso – ysth

+0

oh, vedo (4) usa anche le bareword, solo senza disabilitare strict. E tutti questi che si basano su stringhe come "NAN" e "INF" diventando il "numero" appropriato in contesto numerico falliranno su perls precedenti o dove il runtime C non lo supporta (ad es. Perl fragola o activeperl su Windows) – ysth

+1

Una risposta completa includerebbe una suite di test. – dolmen

5

Utilizzare Data::Float da CPAN. Essa esporta le seguenti funzioni:

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

E contrariamente alle altre soluzioni mezza di lavoro pubblicate qui, ha un testsuite.

+0

Si deve menzionare che il controllo 'Data :: Float' per' NaN' dipende dal supporto 'NaN' sulla piattaforma. –

0

quando ho cercato ho ottenuto questo sito (qui) e http://www.learning-perl.com/2015/05/perls-special-not-a-numbers/

L'articolo collegato sottolinea che "nan" == "nan" non è mai vero, quando l'attuazione c sottostante supporta NaN perché Nan non può corrispondere per sé .

Questo è ben illustrato con

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

Credo che il rischio di voi l'esecuzione di codice in un ambiente dove il Perl ha degradato grazia e il codice non è potrebbe essere abbastanza basso in modo che non si preoccupi troppo .

E, naturalmente, se non si vuole perl a interpolare come un numero, utilizzare 'eq' non '=='

Problemi correlati