Perl Jam VI: April Trolls
为了一个愚人节玩笑,我想模仿Perl Jam马戏团,其中作者有个想法认为有什么不对劲,但解释却半对半错。我写了Perl Jam VI: The Return of the Camel。
我觉得如果我在第一个例子足够聪明并且越来越懒惰的话,我可能会欺骗一些人。我可能太聪明了,但我也认为愚人节可能已经过去了。不仅如此,我仍然因为没能好好解释事情或给出适当的指导而感到愧疚。
Perl的四舍五入问题
对于真正关注数字的人来说,四舍五入是一个问题,因为数值函数中微小的偏差可能会导致结果偏差。大多数人可能永远不会关心这个问题,因为他们不需要关心。然而,我曾经处理过来自核物理实验的大量数据,那里可能需要考虑这一点。
Perl的特殊问题是它依赖于别人的决定。当我刚开始教Perl时,我的许多学生都有C语言的经验。他们知道他们的libc的问题。《perl》将许多决定推迟给了那个libc。这意味着你可能会得到不同《perl》的不同结果。Perl几乎可以在任何地方运行,但它不能保证你会在任何地方得到相同的答案。
关于不同方法的文献有很多,而且方法不止几种。仅仅这个事实就说明人们对于它应该如何工作并不一致。如果你认为四舍五入可能会影响你的结果,你应该知道你有多种方法来处理它。《Math::Round》可以处理其中大多数。
负数的模数
模数运算符更有趣,因为它实际上有一些问题和未定义的行为。我展示了操作数组合的表格,并指出哪些在Perl中是定义的。一些情况没有定义的行为。
我认为很少有人会认真对待这一部分,因为模数运算符并不那么受欢迎。《integer pragma可能可以解决这个问题
内部,使用的是本地整数算术(由你的C编译器提供)。这意味着Perl自己的算术运算语义可能没有得到保留。一个常见的麻烦来源是负数的模数,Perl以一种方式执行,但你的硬件可能以另一种方式执行。
StackOverflow问题Perl: understanding modulo operation on negative numbers更详细地介绍了Perl的行为。
如果这对你应用程序很重要,你可以实现你自己的模数运算(可能在Inline::C中?)以精确地按照你的喜好执行,无论你在哪里运行程序,都能得到你期望的结果。
伪造的随机数
当我们说“随机数”时,经验丰富的程序员通常理解他们实际上并没有使用随机的数字。它们是伪随机的,尽管说起来有点多。我们缩短它为“随机”以使句子更简洁。如果你在播种随机数生成器,你使用的是伪造的。
对于奇数作业分配或选择尚未使用过的唯一值,Perl 的 rand 可能是可行的。如果您正在做需要真实随机性的事情,您不想使用确定性方法。您需要“真正的”随机数。
有几个模块提供了更好的来源接口
Net::Random 可以连接到提供随机数的互联网服务。但是,您必须信任互联网。
Crypt::Random 连接到本地的 /dev/random。这使用环境噪声来生成字节。但是,/dev/urandom 设备可能会降低到伪随机数。它们都不是长序列数字的好来源。
Entropy Key 是一个小型 USB 设备,有助于填充 /dev/random 设备的熵汇。这允许您更频繁地从设备中读取,而不会陷入伪随机数。
Random.org 提供基于大气噪声的数据。在 StackOverflow 问题 如何生成一个不使用循环的随机值数组? 中,我介绍了一种覆盖 Perl 的 rand 以使用此来源的方法。其他一些答案也很说明问题。
与大多数其他事情一样,没有涵盖所有用途的答案。您发现其他来源是程序员的必经之路。
Perl 允许任何人编程
我开玩笑说,Perl 的真正问题是它的存在,本质上,人们可以用来使用它。这是关于世界上最安全的计算机的笑话的一种变化,那是一台关闭的、封装在混凝土中并沉到海底的计算机。而且,我们甚至不确定那时。
但是,我还有一个更有趣的观点。尽管有技术限制或潜在问题,无论是已记录的还是未记录的,都是人编写程序和决定程序将做什么。了解语言的语法是开始,但最大的失败来自编程中的人类决策。为了娱乐说明这个想法,您可能会喜欢 Paul Fenwick 的 失败的插图历史。
本文最初发布在 PerlTricks.com 上。
标签
brian d foy
brian d foy 是一名 Perl 训练师和作家,同时也是 Perl.com 的资深编辑。他是 Mastering Perl,Mojolicious Web Clients,Learning Perl Exercises 的作者,以及 Programming Perl,Learning Perl,Intermediate Perl 和 Effective Perl Programming 的合著者。
浏览他们的文章
反馈
这篇文章有什么问题吗?请通过在 GitHub 上打开问题或拉取请求来帮助我们。