Например, (-3) % 2
вернет -1
вместо 1
.
Каков предпочтительный способ получить положительный остаток в Scala? Например, (((-3) % 2) + 2) % 2
или abs(-3 % 2)
?
Например, (-3) % 2
вернет -1
вместо 1
.
Каков предпочтительный способ получить положительный остаток в Scala? Например, (((-3) % 2) + 2) % 2
или abs(-3 % 2)
?
В scala, почему оператор остатка (%) возвращает отрицательное число?
Существуют различные соглашения для знака результата операции по модулю; В Википедии есть хорошая статья об этом. scala, как и большинство, но далеко не все языки программирования, результат принимает знак дивиденда (-3
в вашем случае).
Каков предпочтительный способ получить положительный остаток в Scala?
Я сомневаюсь, что в общем согласен предпочтительный способ; если бы это был я, используйте Math.floorMod
, который дает результат со знаком делителя (2
в вашем примере) вместо дивиденда (это doesn 't означает только то же значение, что и %
с другим знаком, см. связанный JavaDoc для деталей). Или просто if
после (if (result < 0) { result += M; }
[где M
- это делитель, 2
в вашем примере]).
Правильный способ получить положительный модуль - добавить делитель к отрицательному модулю:
(-18 % 5) + 5
Принимая абсолютное значение, вы получите неправильное решение в этом случае, хотя оно будет работать, если делитель окажется равным 2.
Если вы не знаете знака дивиденда, вы можете сделать что-то вроде этого:
((dividend % divisor) + divisor) % divisor
Использование math.abs(-x % y)
обычно не дает такого же поведения, как возврат положительного модуля:
scala> math.abs(-7 % 3)
res46: Int = 1
Но не то, что питон (язык, который возвращает положительный модуль) говорит:
In [14]: -7 % 3
Out[14]: 2
Если мы посмотрим на приращения 3 от -7:
-7, -4, -1, 2, ..
scala
останавливается на -1
, а python
останавливается на 2
.
Я хотел бы добавить что-то к существующим ответам. Мой предпочтительный способ получить положительный остаток - добавить новый метод к типу 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}
}
}
В файле, где вы хотите использовать метод, импортируйте неявный класс с помощью:
import Extensions._
Теперь вы можете сделать:
(-3).positiveMod(2)
Вы также можете поместить неявный класс в объект пакета, поэтому вам не нужно импортировать его при вызове функции из того же пакета.
Например, если вы хотите отфильтровать все нечетные элементы из массива, игнорируя отрицательные или положительные значения, вы можете сделать так:
arr.filter {x = > Math.abs(x% 2) == 1}