Jak utworzyć lub przetestować dla NaN lub nieskończonej wartości w Perlu?Jak utworzyć lub przetestować dla NaN lub nieskończoności w Perlu?
Odpowiedz
Oto dość niezawodny sposób:
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));
}
wyjściowa wynosi:
inf: isinf: 1, isnan: 0, signbit: 0
-inf: isinf: 1, isnan: 0, signbit: 1
nan: isinf: 0, isnan: 1, signbit: 0
print "Is NaN\n" if $a eq 'nan';
print "Is Inf\n" if $a eq 'inf' or $a eq '-inf';
EDIT: Fixed do minus nieskończoności.
Ktoś, kto nie głosuje na tę odpowiedź, pozwala ci opuścić stanowisko, jeśli nie poczujesz się zawstydzony. W ten sposób działa absolutnie idealnie w perlu. Jeśli $ a jest liczbą reprezentującą ciąg znaków, będzie to "nan" lub "inf" tylko wtedy, gdy będzie to wartość NaN lub Inf. –
Co, jeśli $ a nie jest liczbą, ale faktycznie jest łańcuchem "nan"? –
@Ryan: String "nan" nie jest liczbą oczywiście. Rozwiązanie Ystha działa dokładnie tak samo. Sprawdź 'perl -le 'sub isnan {! zdefiniowany ($ _ [0] <=> 9 ** 9 ** 9)}; print isnan ("nan") ", jeśli mi nie ufasz. –
Osobiście użyłbym Math::BigFloat
(lub BigInt
) do wszystkiego, co ma dotknąć nieskończoności NaN
.
Po co na nowo zaprojektować koło za pomocą rozwiązania do hackowania, gdy istnieją już moduły, które wykonują zadanie?
Zwięzła odpowiedź, która działa.
1: Jak stworzyć "NAN" zmienną do wyjścia (do printf, na przykład):
{no strict 'subs'; $NAN="NAN"+1;}
2: Jak przetestować dla "NAN" (wygląda jak ASCII Art):
sub isnan {!($_[0]<=0||$_[0]>=0)}
3: Jak stworzyć "INF" i INFN zmienne:
{$INF="INF"+1; $INFN=-"INF"+1}
4: Jak przetestować dla "INF" (dowolnego znaku):
sub isinf {($_[0]==+"INF")||($_[0]==-"INF")}
(1) i (3) nie różnią się od "$ NAN =" NAN "+1;', '$ INF =" INF "+1; $ INFN = - "INF"; 'po prostu bardziej gadatliwy – ysth
oh, widzę (4) również używa barewords, tylko bez wyłączania strict. Wszystkie te, które polegają na tym, że ciągi takie jak "NAN" i "INF" stają się odpowiednią "liczbą" w kontekście liczbowym, zawiodą w starszych perls lub gdy środowisko wykonawcze C nie obsługuje tego (np. Strawberry perl lub activeperl w oknach) – ysth
Odpowiedź "kompleksowa" obejmowałaby zestaw testowy. – dolmen
Użyj Data::Float z CPAN. Eksportuje następujące funkcje:
float_is_infinite(
)float_is_nan()
- ...
I w przeciwieństwie do innych rozwiązań pół pracy zamieszczone tutaj, to ma testsuite.
Należy wspomnieć, że kontrola 'Data :: Float' dla' NaN' zależy od wsparcia 'NaN' na platformie. –
Kiedy szukałem mam ten serwis (tutaj) i http://www.learning-perl.com/2015/05/perls-special-not-a-numbers/
prowadzi link artykule wskazuje, że „nan” == „nan” nigdy nie jest prawdziwe, gdy instrumentem bazowym realizacja c obsługuje NaN ponieważ Nan nie może równać się .
to ładnie ilustrowany
die "This perl does not support NaN!\n" if "NaN" == "NaN";
Chyba ryzyko działa Ci kod w środowisku, w którym perla degradacji wdziękiem i kod nie może być wystarczająco niskie, aby nie martwić się zbytnio .
I oczywiście, jeśli nie chcesz Perl interpolować jako liczbę, użyj „eq” Nie „==”
dniu 5.10 i wyżej, gdzie biblioteka C wspiera go, tylko 0+ „NaN” , 0+ "inf" lub 0 + "- inf" też działa. – ysth
Bardzo energiczny z ciebie: 13 minut temu, zadajesz pytanie; 11 minut temu, odpowiadasz; 9 minut temu, publikujesz komentarz. Powinieneś kupić sobie piwo lub coś takiego. – Telemachus
@Telemachus: Z wyjątkiem tego, że nie piję rzeczy ... – ysth