在 Scala 中,为什么余数 (%) 运算符 return 可以是负数?
In Scala, why could remainder (%) operator return a negative number?
例如,(-3) % 2
将 return -1
而不是 1
。
在 Scala 中获得正余数的首选方法是什么?比如(((-3) % 2) + 2) % 2
,或者abs(-3 % 2)
?
In scala, why could remainder (%) operator return a negative number?
模运算结果的符号有不同的约定; Wikipedia has a good article on it。 Scala 与大多数但绝不是所有编程语言一样,其结果采用红利符号(在您的情况下为 -3
)。
What is the preferred way to get the positive remainder in Scala?
我怀疑是否存在公认的首选方式;如果是我,要么使用 Math.floorMod
,它给出的结果带有除数符号(在您的示例中为 2
)而不是股息(这不仅仅意味着与 [= 相同的值13=] 带有不同的符号,有关详细信息,请参阅链接的 JavaDoc)。或者只是一个 if
之后(if (result < 0) { result += M; }
[其中 M
是除数,2
在你的例子中])。
使用 math.abs(-x % y)
通常不会产生与返回正模数相同的行为:
scala> math.abs(-7 % 3)
res46: Int = 1
但这不是 python(一种 returns 正模数的语言)所说的:
In [14]: -7 % 3
Out[14]: 2
如果我们看从-7开始递增3:
-7, -4, -1, 2, ..
scala
停在-1
,python
停在2
。
获得正模数的正确方法是将除数加到负模数上:
(-18 % 5) + 5
在这种情况下取绝对值会给你错误的解决方案,但如果除数恰好是 2,它会起作用。
如果你不知道红利的符号,你可以这样做:
((dividend % divisor) + divisor) % divisor
例如,如果你想从一个数组中过滤掉所有奇数元素,忽略负数或正数,你可以这样做:
arr.filter{x => Math.abs(x%2)==1}
我想对现有答案进行补充。我首选的获取正余数的方法是向 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}
}
}
在您要使用该方法的文件中,导入隐式 class :
import Extensions._
现在您可以:
(-3).positiveMod(2)
您还可以将隐式 class 放在一个包对象中,这样当您从同一个包调用函数时就不需要导入。
例如,(-3) % 2
将 return -1
而不是 1
。
在 Scala 中获得正余数的首选方法是什么?比如(((-3) % 2) + 2) % 2
,或者abs(-3 % 2)
?
In scala, why could remainder (%) operator return a negative number?
模运算结果的符号有不同的约定; Wikipedia has a good article on it。 Scala 与大多数但绝不是所有编程语言一样,其结果采用红利符号(在您的情况下为 -3
)。
What is the preferred way to get the positive remainder in Scala?
我怀疑是否存在公认的首选方式;如果是我,要么使用 Math.floorMod
,它给出的结果带有除数符号(在您的示例中为 2
)而不是股息(这不仅仅意味着与 [= 相同的值13=] 带有不同的符号,有关详细信息,请参阅链接的 JavaDoc)。或者只是一个 if
之后(if (result < 0) { result += M; }
[其中 M
是除数,2
在你的例子中])。
使用 math.abs(-x % y)
通常不会产生与返回正模数相同的行为:
scala> math.abs(-7 % 3)
res46: Int = 1
但这不是 python(一种 returns 正模数的语言)所说的:
In [14]: -7 % 3
Out[14]: 2
如果我们看从-7开始递增3:
-7, -4, -1, 2, ..
scala
停在-1
,python
停在2
。
获得正模数的正确方法是将除数加到负模数上:
(-18 % 5) + 5
在这种情况下取绝对值会给你错误的解决方案,但如果除数恰好是 2,它会起作用。
如果你不知道红利的符号,你可以这样做:
((dividend % divisor) + divisor) % divisor
例如,如果你想从一个数组中过滤掉所有奇数元素,忽略负数或正数,你可以这样做:
arr.filter{x => Math.abs(x%2)==1}
我想对现有答案进行补充。我首选的获取正余数的方法是向 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}
}
}
在您要使用该方法的文件中,导入隐式 class :
import Extensions._
现在您可以:
(-3).positiveMod(2)
您还可以将隐式 class 放在一个包对象中,这样当您从同一个包调用函数时就不需要导入。