How do I create or test for NaN or infinite values in Perl?
+5
A:
Here's a fairly reliable way:
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));
}
Output is:
inf: isinf: 1, isnan: 0, signbit: 0
-inf: isinf: 1, isnan: 0, signbit: 1
nan: isinf: 0, isnan: 1, signbit: 0
ysth
2009-07-26 23:07:08
On 5.10 and above, where the C library supports it, just 0+"nan", 0+"inf", or 0+"-inf" work too.
ysth
2009-07-26 23:09:05
Very energetic of you: 13 minutes ago, you ask the question; 11 minutes ago, you answer it; 9 minutes ago, you post a comment. You should buy yourself a beer or something.
Telemachus
2009-07-26 23:21:02
@Telemachus: Except that I don't drink the stuff...
ysth
2009-07-26 23:26:09
Interesting, where does the 9 to the 9th to the 9th power come from? Is there a special significance or is it just an easy way to get a number big enough to blow up a variety of float specifications?
daotoad
2009-07-27 03:17:55
@daotoad: yes, just an easy way. Some code unfortunately used things like 100**1000, which is infinite with IEEE double precision, but not infinite with long doubles.
ysth
2009-07-27 03:31:54
Just don't use this under bigint or you'll wonder why your program is hung.
brian d foy
2009-07-27 04:17:34
Right, under bigint, use Math::BigInt->bnan(), ->binf(), or ->binf('-').
ysth
2009-07-27 04:41:26
I was more concern with cases where someone turned on bigint and you didn't notice. :)
brian d foy
2009-07-27 21:57:17
+4
A:
print "Is NaN\n" if $a eq 'nan';
print "Is Inf\n" if $a eq 'inf';
Hynek -Pichi- Vychodil
2009-07-27 09:08:47
One who down vote this answer, let you leave post if you not feel ashamed. This way works absolutely perfect in perl. If $a is number than string representation will be 'nan' or 'inf' only if it is NaN or Inf value.
Hynek -Pichi- Vychodil
2009-10-06 14:39:28
@Ryan: String "nan" is not a number of course. ysth's solution works exactly same. Check `perl -le 'sub isnan { ! defined( $_[0] <=> 9**9**9 ) }; print isnan("nan")'` if you don't trust me.
Hynek -Pichi- Vychodil
2010-10-06 19:20:04