如何在 Perl 中创建或测试 NaN 或无穷大?

问题描述 投票:0回答:7

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

perl nan infinity
7个回答
15
投票
print "Is NaN\n" if $a eq 'nan';
print "Is Inf\n" if $a eq 'inf' or $a eq '-inf';

编辑:固定为负无穷大。


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

7
投票

使用 CPAN 中的 Data::Float。它导出以下功能:

  • float_is_infinite(
  • float_is_nan()
  • ...

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


7
投票

就我个人而言,我会使用

Math::BigFloat
(或
BigInt
)来表示任何会触及无穷大
NaN
的东西。

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


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' 而不是 '=='


0
投票
sub is_nan($) { $_[0] != $_[0] }
sub is_inf($) { scalar $_[0] =~ /^-?inf$/ }

NaN 在输入上是

NaN
(但不是在输出上;那里是
nan
(无论出于何种原因))。 Perl 理解
inf
-inf
:

  DB<31> x is_nan 7
0  ''
  DB<32> x is_nan NaN
0  1
  DB<33> x is_nan 'NaN'
0  1
  DB<34> x is_nan inf
0  ''
  DB<38> x is_inf 4
0  ''
  DB<39> x is_inf inf
0  1
  DB<40> x is_inf -inf
0  1
  DB<41> x is_inf '-inf'
0  1
  DB<42> x is_nan 'NaN' + 3
0  1
  DB<43> x is_nan 'NaN' + inf
0  1
  DB<44> x is_nan inf
0  ''
  DB<45> x is_nan inf - inf
0  1
  DB<46> x is_nan -inf + inf
0  1
  DB<47> x inf > 0
0  1
  DB<48> x inf < 0
0  ''
  DB<49> x -inf > 0
0  ''
  DB<50> x -inf < 0
0  1

-2
投票

以下是有效的简洁答案。

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")}
© www.soinside.com 2019 - 2024. All rights reserved.