Оператор по модулю Java %
основан на усеченном делении (см. Википедия: операция по модулю).
5%3
производит2
(обратите внимание, что5/3
производит1
)5%(-3)
производит2
(обратите внимание, что5/(-3)
производит-1
)(-5)%3
производит-2
(обратите внимание, что(-5)/3
производит-1
)(-5)%(-3)
производит-2
(обратите внимание, что(-5)/(-3)
производит1
)
В информатике, имея два целых числа a
и n
, n
›0, иногда полезно получить уникальное целое число r
в пределах [a,n[
, которое конгруэнтно a
по модулю n
.
Вопрос
Есть ли в Java эффективный универсальный оператор / метод, который соблюдает эту спецификацию по модулю?
Это сделано для того, чтобы не переписывать его в каждом проекте, где это необходимо ...
Разное
Я нашел много вопросов об этой проблеме по stackoverflow, большинство из которых сбивает с толку различные реализации по модулю. Если вас просто беспокоят результаты операции по модулю для отрицательных чисел, ниже приведены некоторые реализации, основанные на операторе Java %
, которые могут быть полезны.
Общий взлом
Поскольку мы почти не используем отрицательный делитель, эта реализация возвращает евклидово значение по модулю, когда n > 0
.
static int mod(int a, int n){
return a<0 ? (a%n + n)%n : a%n;
}
mod( 5, 3)
производит2
mod(-5, 3)
производит1
Евклидов по модулю
static int euclideanModulo(int a, int n){
return n<0 ? euclideanModulo(a, -n) : mod(a, n);
}
euclideanModulo( 5, 3)
производит2
euclideanModulo(-5, 3)
производит1
euclideanModulo( 5,-3)
производит2
euclideanModulo(-5,-3)
производит1
Напольные по модулю
static int flooredModulo(int a, int n){
return n<0 ? -flooredModulo(-a, -n) : mod(a, n);
}
flooredModulo( 5, 3)
производит2
flooredModulo(-5, 3)
производит1
flooredModulo( 5,-3)
производит-1
flooredModulo(-5,-3)
производит-2
Math.floor()
(JavaDocs) - person Killrawr   schedule 08.02.2013Math.floor()
хуже любого из вышеперечисленных решений. - person UmNyobe   schedule 08.02.2013a - n * (int)Math.floor((double)a/n);
математически верен для напольного модуля, но не эффективен и не универсален. - person boumbh   schedule 08.02.2013(-5)magicmod(-3)
дать?-2
или2
? - person UmNyobe   schedule 08.02.2013a
иn
,n > 0
, вернуть уникальное целое числоr
в пределах[a,n[
, которое конгруэнтноa
по модулюn
. У меня уже есть эффективная реализация, я просто хотел убедиться, что не изобретаю велосипед. Я был бы удивлен, что в Java нет более универсального способа сделать это. Может, я просто секу волосы. Если так, то ответ будет простым нет. - person boumbh   schedule 08.02.2013array[mod(i++, array.length)]
. Это не насущная проблема, скорее любопытный вопрос для моего личного совершенствования. - person boumbh   schedule 08.02.2013euclideanModulo(5, -3)
дает1
, это неверно, потому что частное не является целым числом:a = bq + r
,5 = -3q + 1
,q = -4/3
. Та же проблема сeuclideanModulo(-5,-3)
, который, по вашему мнению, выдает2
. - person Vlastimil Ovčáčík   schedule 28.03.20155 % -3
должно быть2
и-5 % -3
должно быть1
, я внесу изменения в вопрос и другой свой комментарий. - person boumbh   schedule 30.03.2015