我正在学习Perl (5.14),我有点困在带负数的模上。举个例子,让我们看一下10%3的变化。
首先,
perl -le 'print -10%-3'正如预期的那样,它产生了-1。
但,
perl -le 'print -10%3'产2。
和,
perl -le 'print 10%-3'产-2。
我不明白最后两个结果。我预期只有1或-1的结果会有10%3的变动,为何要返回2 (正数或负数)?
发布于 2015-08-19 08:37:14
您发现了一个perl5规范错误/特性,很可能永远不会修复。这种模块化与i_modulo错误的描述甚至是这样的,它有一个奇怪的模块化定义,这偏离了libc中的数学定义和实现,即标准C库。
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)."因此-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)
}请注意,如果这两个参数都是文字整数常量,则结果在编译时是常量折叠的。但是,即使这两个参数显然都是整数类型,常量文件夹也使用泛型模运算符,而不是特定的i_modulo运算符,后者是在“使用整数”下使用的。或者使用类型化的perl扩展,在编译时两个args都是整数。
这个bug甚至升级到perl6,在鹦鹉和moar中定义,就像在perl5中一样。我不确定jvm后端是否也使用黑客来使用奇怪的perl5定义。
发布于 2013-12-19 21:21:32
Perl通常使用与机器无关的算术模运算符.
这是取自Perl文档:乘法运算符的
二进制%是模操作符,它计算第一个参数相对于第二个参数的除法余数。
给定整数操作数$a和$b:
$b为正,则$a % $b为$a减去$b的最大倍数小于或等于$a。$b是负的,那么$a % $b是$a减去$b的最小倍数,也就是不小于$a (也就是说,结果将小于或等于零)。$a和$b是浮点值,且$b的绝对值(即abs($b))小于(UV_MAX + 1),则操作中将只使用$a和$b的整数部分(注:此处UV_MAX表示无符号整数类型的最大值)。abs($b))的绝对值大于或等于(UV_MAX + 1),则%计算方程($r = $a - $i*$b)中的浮点余数$r,其中$i是一个整数,使$r具有与右操作数$b相同的符号(而不是左操作数$a类C函数fmod()),绝对值小于d40。注意,当use integer在作用域中时,%允许您直接访问由C编译器实现的模块化操作符。对于负操作数,这个运算符没有很好的定义,但是它将执行得更快。
https://stackoverflow.com/questions/20691861
复制相似问题