检查 Perl 模块中无穷大的最佳方法是什么?

发布于 2024-09-26 16:20:27 字数 804 浏览 4 评论 0原文

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

但是,如果我的模块的用户决定使用大数字模块之一(例如 use bigint;),然后他们使用 inf 或 < code>Math::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... 实现,或者我应该自己推出?

In one of my modules, I have to deal with the concept of infinity. To date, I have been using 9**9**9 as positive infinity, and this seems to work well, is fast, and seems to be what perl's internals use as infinity.

However, things get a bit dicey if a user of my module decides to use one of the big number modules (like use bigint;), and then they use inf or Math::BigInt->binf() to represent infinity.

In some places it seems to work fine, but in others, comparisons that should be true or should be false end up the wrong way round leading to difficult to track down bugs.

I would like to support the various other notions of infinity with something that will work with both normal perl numbers, and arbitrary precision numbers.

But I also have concerns about performance since some of my comparisons to infinity occur in tight inner loops. Obviously inf from Math::BigInt is going to be slower than 9**9**9 (due to either calling tied or overloaded methods on each access). Has anyone dealt with this problem in the past? If so, what was your solution?

I've thought about using my own constant for infinity, defined something like this:

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

And then adding the caveat to my module that any bignum modules should be loaded first. Does this sound sensible? Is there a reliable implementation of if_any_bignum... out there, or should I roll my own?

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

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

发布评论

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

评论(1

半衾梦 2024-10-03 16:20:27

Math::BigInt 提供了一个 is_inf 方法。它可以检测常规 Perl 数字的无穷大,包括 Perl 的内置 inf,例如按 9**9**9 返回,以及任何类型的 < code>Math::Big* 实例或使用 bigint 时获得的那些神奇的东西。加载 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 provides an is_inf method. It can detect infinity for both regular Perl numbers, including Perl's built-in inf, such as return by 9**9**9, as well as any sort of Math::Big* instance or those magic thingies you get when you're using bigint. Loading Math::BigInt comes with barely any overhead at all - none comparable to using bigint anyway - and is a core module since the very beginning of 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

You might also want to have a look at the implementation of that method if you really wanted to avoid loading Math::BigInt at all. It's easy enough to inline into other code with just slight modifications, although I would really recommend just using the functionality from the module directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文