Java 在 Scala 中,为什么余数 (%) 运算符会返回负数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30003811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Scala, why could remainder (%) operator return a negative number?
提问by Hanfei Sun
For example, (-3) % 2
will return -1
instead of 1
.
例如,(-3) % 2
将返回-1
而不是1
。
What is the preferred way to get the positive remainder in Scala? Such as (((-3) % 2) + 2) % 2
, or abs(-3 % 2)
?
在 Scala 中获得正余数的首选方法是什么?比如(((-3) % 2) + 2) % 2
, 或者abs(-3 % 2)
?
采纳答案by T.J. Crowder
In scala, why could remainder (%) operator return a negative number?
在 Scala 中,为什么余数 (%) 运算符会返回负数?
There are different conventions for the sign of the result of a modulo operation; Wikipedia has a good article on it. Scala, like most but by no means all programming languages, has the result take the sign of the dividend (the -3
in your case).
模运算结果的符号有不同的约定;维基百科有一篇关于它的好文章。Scala 像大多数但绝不是所有编程语言一样,结果带有红利的符号(-3
在您的情况下)。
What is the preferred way to get the positive remainder in Scala?
在 Scala 中获得正余数的首选方法是什么?
I doubt there's a generally-agreed preferred way; if it were me, either use Math.floorMod
, which gives a result with the sign of the divisor (2
in your example) instead of the dividend (this doesn't just mean the same value as %
with a different sign, see the linked JavaDoc for details). Or just an if
afterward (if (result < 0) { result += M; }
[where M
is the divisor, 2
in your example]).
我怀疑是否存在普遍认可的首选方式;如果是我,要么使用Math.floorMod
,它给出的结果带有除数的符号(2
在您的示例中)而不是被除数(这不仅仅意味着%
与不同符号的值相同,有关详细信息,请参阅链接的 JavaDoc) . 或者只是if
之后(if (result < 0) { result += M; }
[在你的例子中M
,除数2
在哪里])。
回答by Akavall
Using math.abs(-x % y)
does not usually yield the same behavior as returning a positive modulus:
使用math.abs(-x % y)
通常不会产生与返回正模数相同的行为:
scala> math.abs(-7 % 3)
res46: Int = 1
But that's not what python (a language that returns a positive modulus) says:
但这不是 python(一种返回正模数的语言)所说的:
In [14]: -7 % 3
Out[14]: 2
If we look at increments of 3 from -7:
如果我们查看从 -7 开始的 3 增量:
-7, -4, -1, 2, ..
scala
stops at -1
, and python
stops at 2
.
scala
停在-1
,python
停在2
。
回答by Kevin
The correct way to get the positive modulus is to add the divisor to the negative modulus:
得到正模数的正确方法是在负模数上加上除数:
(-18 % 5) + 5
Taking the absolute value will give you the wrong solution in this case, though it will work if the divisor happens to be 2.
在这种情况下,取绝对值会给你错误的解决方案,但如果除数恰好是 2,它会起作用。
If you don't know the sign of the dividend, you can do something like this:
如果你不知道红利的符号,你可以这样做:
((dividend % divisor) + divisor) % divisor
回答by Haimei
For example, if you want to filter out all odd elements from an array, ignoring negative or positive, you can do like this:
例如,如果您想从数组中过滤掉所有奇数元素,忽略负数或正数,您可以这样做:
arr.filter{x => Math.abs(x%2)==1}
arr.filter{x => Math.abs(x%2)==1}
回答by user42723
I would like to add something to the existing answers. My preferred way to get the positive remainder is to add a new method to the Int type as follows:
我想在现有答案中添加一些内容。我获得正余数的首选方法是向 Int 类型添加一个新方法,如下所示:
object Extensions
{
implicit class ExtendedInt (val i: Int) extends AnyVal {
def positiveMod (m: Int) = {val x = i % m; if (x < 0) x + m else x}
}
}
In the file where you want to use the method, import the implicit class with:
在要使用该方法的文件中,使用以下命令导入隐式类:
import Extensions._
Now you can do:
现在你可以这样做:
(-3).positiveMod(2)
You could also put the implicit class in a package object so you don't need to import when calling the function from the same package.
您还可以将隐式类放在包对象中,这样在从同一个包调用函数时就不需要导入。