【问题标题】:What is the best way to check for infinity in a Perl module?在 Perl 模块中检查无穷大的最佳方法是什么?
【发布时间】:2011-04-20 21:26:37
【问题描述】:

在我的一个模块中,我必须处理无穷大的概念。迄今为止,我一直使用9**9**9 作为正无穷大,这似乎运作良好,速度很快,并且似乎是 perl 的内部使用的无穷大。

但是,如果我的模块的用户决定使用其中一个大数字模块(如use bigint;),然后他们使用infMath::BigInt->binf() 来表示无穷大,事情就会变得有点冒险。

在某些地方它似乎工作正常,但在其他地方,应该为真或应该为假的比较以错误的方式结束,导致难以追踪错误。

我想支持各种其他的无穷大概念,它适用于普通的 perl 数字和任意精度的数字。

但我也担心性能,因为我与无穷大的一些比较发生在紧密的内部循环中。显然,来自Math::BigIntinf 将比9**9**9 慢(由于在每次访问时调用绑定或重载方法)。过去有没有人处理过这个问题?如果是这样,您的解决方案是什么?

我考虑过使用自己的无穷大常数,定义如下:

use constant INF => if_any_bignum_modules_loaded() 
                    ? Math::BigInt->binf 
                    : 9**9**9;

然后将警告添加到我的模块中,即应首先加载任何 bignum 模块。这听起来合理吗?是否有可靠的if_any_bignum... 实现,或者我应该自己推出?

【问题讨论】:

  • @Ether => 请在投票结束前阅读问题,该问题中的答案均不涵盖该问题...
  • 好的,不是很清楚,因为问题是相同的。
  • @Ether => 这个问题与如何最好地支持可能会或可能不会使用 bignums 的最终用户有关,而不会对不使用 bignums 的用户造成性能影响。链接的问题简要涉及其中一个 cmets 中与 bignums 相关的问题,但分析简洁、不完整,并且没有提供解决方案。在发布此问题之前,我查看了该问题以及搜索 [perl] infinity 时出现的所有其他问题。

标签: perl module biginteger bignum infinity


【解决方案1】:

Math::BigInt 提供了一个is_inf 方法。它可以检测两个常规 Perl 数字的无穷大,包括 Perl 的内置 inf,例如由 9**9**9 的返回,以及任何类型的 Math::Big* 实例或您在使用 @987654326 时获得的那些神奇事物@。加载 Math::BigInt 几乎没有任何开销 - 无论如何都无法与使用 bigint 相比 - 并且从 perl 5 一开始就是一个核心模块。

use 5.010;
use Math::BigInt;

say Math::BigInt->is_inf(42);
say Math::BigInt->is_inf(9**9**9);
say Math::BigInt->is_inf(Math::BigInt->binf);

__END__
0
1
1

如果您真的想完全避免加载Math::BigInt,您可能还想看看该方法的实现。只需稍作修改就可以很容易地内联到其他代码中,尽管我真的建议直接使用模块中的功能。

【讨论】:

  • 对于所有非内部循环测试,这绝对是一个很好的包罗万象的解决方案。我将不得不进行基准测试以查看对内部循环的性能影响。
  • 如果你发现它对于你正在做的事情来说太慢了,并想办法以更快的方式实现相同的功能,我很乐意将你的补丁应用到 Math::BigInt并将它们运送到 CPAN。
  • 听起来不错,我会看看我能做什么。我想将所有正则表达式匹配更改为对index 的调用将是一个开始。
  • => inf_nan.t 需要另一个测试,Math::BigInt->is_inf(9**9**9) 似乎在草莓 perl 上至少在 64 位平台上失败了。底层 clib 为 9**9**9 返回 1.#INFBigInt 映射到 NaN。 5.8.9 和 5.12 的结果相同
猜你喜欢
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 2015-05-10
  • 1970-01-01
  • 2010-10-11
  • 2013-02-21
  • 2013-06-22
  • 1970-01-01
相关资源
最近更新 更多