26

如何在 Perl 中创建或测试 NaN 或无限值?

4

6 回答 6

15

这是一个相当可靠的方法:

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

输出是:

inf:    isinf: 1,   isnan: 0,   signbit: 0
-inf:   isinf: 1,   isnan: 0,   signbit: 1
nan:    isinf: 0,   isnan: 1,   signbit: 0
于 2009-07-26T23:07:08.517 回答
15
print "Is NaN\n" if $a eq 'nan';
print "Is Inf\n" if $a eq 'inf' or $a eq '-inf';

编辑:固定为负无穷大。

于 2009-07-27T09:08:47.020 回答
7

就个人而言,我会使用Math::BigFloat(或BigInt)来表示任何会触及NaN.

既然已经有模块可以完成这项工作,为什么还要用 hack 解决方案重新发明轮子?

于 2009-07-29T08:50:25.993 回答
7

使用来自 CPAN 的Data::Float 。它导出以下函数:

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

与此处发布的其他半工作解决方案相反,它有一个testsuite

于 2013-03-20T14:58:21.177 回答
0

当我搜索时,我得到了这个网站(这里)和http://www.learning-perl.com/2015/05/perls-special-not-a-numbers/

链接的文章指出,当底层 c 实现支持 NaN 因为 Nan 无法匹配自身时,“nan” == “nan” 永远不会为真。

这很好地说明了

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

我猜想在 perl 已经正常降级并且代码还不够低的环境中运行代码的风险可能足够低,因此您不必太担心。

当然,如果您不希望 perl 插入数字,请使用 'eq' 而不是 '=='

于 2016-06-07T19:03:59.820 回答
-1

简洁有效的答案如下。

1:如何为输出创建一个“NAN”变量(例如到 printf):

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

2:如何测试“NAN”(看起来像 ascii 艺术):

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

3:如何创建“INF”和INFN变量:

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

4:如何测试“INF”(任何符号):

sub isinf {($_[0]==+"INF")||($_[0]==-"INF")}
于 2012-10-19T17:32:02.617 回答