首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl:理解负数的模运算(例如-10%3)

Perl:理解负数的模运算(例如-10%3)
EN

Stack Overflow用户
提问于 2013-12-19 21:17:13
回答 2查看 3.3K关注 0票数 4

我正在学习Perl (5.14),我有点困在带负数的模上。举个例子,让我们看一下10%3的变化。

首先,

代码语言:javascript
复制
perl -le 'print -10%-3'

正如预期的那样,它产生了-1

但,

代码语言:javascript
复制
perl -le 'print -10%3'

2

和,

代码语言:javascript
复制
perl -le 'print 10%-3'

-2

我不明白最后两个结果。我预期只有1或-1的结果会有10%3的变动,为何要返回2 (正数或负数)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-19 08:37:14

您发现了一个perl5规范错误/特性,很可能永远不会修复。这种模块化与i_modulo错误的描述甚至是这样的,它有一个奇怪的模块化定义,这偏离了libc中的数学定义和实现,即标准C库。

http://perldoc.perl.org/perlop.html#Multiplicative-Operators中的文档只描述了一种情况,而不是第二种情况。忘了把整个故事都说出来。

代码语言:javascript
复制
"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行为。

代码语言:javascript
复制
   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定义。

票数 6
EN

Stack Overflow用户

发布于 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编译器实现的模块化操作符。对于负操作数,这个运算符没有很好的定义,但是它将执行得更快。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20691861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档