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

发布于 2024-07-29 17:05:46 字数 32 浏览 4 评论 0原文

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

How do I create or test for NaN or infinite values in Perl?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

江南月 2024-08-05 17:05:46
print "Is NaN\n" if $a eq 'nan';
print "Is Inf\n" if $a eq 'inf' or $a eq '-inf';

编辑:修复负无穷大。

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

EDIT: Fixed for negative infinity.

束缚m 2024-08-05 17:05:46

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

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

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
不回头走下去 2024-08-05 17:05:46

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

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

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

Use Data::Float from CPAN. It exports the following functions:

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

And contrary to the others half-working solutions posted here, it has a testsuite.

倚栏听风 2024-08-05 17:05:46

就我个人而言,我会使用 Math::BigFloat(或 BigInt)来处理任何接近无穷大的 NaN 的情况。

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

Personally, I would use Math::BigFloat (or BigInt) for anything that is going to touch infinity of NaN.

Why reinvent the wheel with a hack solution when there are already modules that do the job?

三生一梦 2024-08-05 17:05:46

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

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

这很好地说明了这一点,

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

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

当然,如果您不希望 Perl 作为数字进行插值,请使用 'eq' 而不是 '=='

When I searched I got this site (here) and http://www.learning-perl.com/2015/05/perls-special-not-a-numbers/

The linked article points out that "nan" == "nan" is never true, when the underlying c implementation supports NaN because Nan cannot match itself.

This is nicely illustrated with

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

I guess the risk of running you code in an environment where perl has degraded gracefully and your code has not might be low enough so that you don't worry too much.

And of course if you don't want perl to interpolate as a number, use 'eq' not '=='

汹涌人海 2024-08-05 17:05:46
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
sub is_nan($) { $_[0] != $_[0] }
sub is_inf($) { scalar $_[0] =~ /^-?inf$/ }

NaN is NaN on input (but not on output; there it's nan (for whatever reason)).
And Perl understands inf and -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
吃→可爱长大的 2024-08-05 17:05:46

下面是有效的简洁答案。

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

Succinct answer that works follows.

1: How to create a "NAN" variable for output (to printf, for example):

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

2: How to test for "NAN" (looks like ascii art):

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

3: How to create an "INF" and INFN variables:

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

4: How to test for "INF" (of any sign):

sub isinf {($_[0]==+"INF")||($_[0]==-"INF")}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文