在Scala中,为什么余数(%)运算符会返回负数?

时间:2022-06-04 01:41:56

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)?

5 个解决方案

#1


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 ifward(if(result <0){result + = M;} [其中M是除数,在你的例子中为2])。

#2


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

#3


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处停止。

#4


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.

您还可以将隐式类放在包对象中,这样在从同一个包调用函数时就不需要导入。

#5


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}

#1


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 ifward(if(result <0){result + = M;} [其中M是除数,在你的例子中为2])。

#2


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

#3


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处停止。

#4


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.

您还可以将隐式类放在包对象中,这样在从同一个包调用函数时就不需要导入。

#5


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}