3 perl
我正在学习 Perl (5.14) 并且我有点坚持使用负数取模。例如,让我们看一下 10%3 的变体。
开始,
perl -le 'print -10%-3'
Run Code Online (Sandbox Code Playgroud)
产量-1
,正如预期的那样。
但,
perl -le 'print -10%3'
Run Code Online (Sandbox Code Playgroud)
产量2
。
和,
perl -le 'print 10%-3'
Run Code Online (Sandbox Code Playgroud)
产量-2
。
我不明白最后两个结果。对于 10%3 的任何变化,我预计只有 1 或 -1。为什么结果应该返回 2,无论是正数还是负数?
您发现了一个很可能永远不会修复的 perl5 规范错误/功能。这个 modulo vs i_modulo 错误甚至被记录为这样,模的奇怪定义偏离了标准 C 库 libc 中的数学定义和实现。
http://perldoc.perl.org/perlop.html#Multiplicative-Operators中的文档只描述了一种情况,而不是第二种情况。并且忘记讲述整个故事。
"If $b is negative, then $a % $b is $a minus the smallest multiple of $b
that is not less than $a (that is, the result will be less than or
equal to zero)."
Run Code Online (Sandbox Code Playgroud)
因此 -13 % 4 是未指定的,13 % -4 被描述为返回 -3,而不是 1。实际上 -13 % 4 返回 3 而不是 -1。
这种 perl5 行为只是在没有use integer
. 随着use integer
你获得正确和快速的 libc 行为。
use integer;
print -13 % 4; # => -1
print 13 % -4; # => 1
print -13 % -4; # => -1 (same with or without use integer)
print 13 % 4; # => 1 (same with or without use integer)
{
no integer;
print -13 % 4; # => 3 (different to libc)
print 13 % -4; # => -3 (different to libc)
print -13 % -4; # => -1 (same with or without use integer)
print 13 % 4; # => 1 (same with or without use integer)
}
Run Code Online (Sandbox Code Playgroud)
请注意,由于两个参数都是文字整数常量,因此结果是在编译时折叠的常量。但即使这两个参数显然都是整数类型,常量文件夹使用通用模运算符,而不是特定的 i_modulo 运算符,它在使用整数下使用。或者使用类型化的 perl 扩展,在编译时两个 args 都是整数。
这个 bug 甚至被提升到 perl6,在 parrot 和 moar 中定义为 perl5。我不确定 jvm 后端是否也使用 hack 来使用奇怪的 perl5 定义。
归档时间: |
|
查看次数: |
2824 次 |
最近记录: |