Лучший способ заставить Java-модуль вести себя так, как должен, с отрицательными числами?

В java, когда вы делаете

a % b

Если a отрицательно, он вернет отрицательный результат, вместо того, чтобы обертывать его так, как нужно. Какой лучший способ исправить это? Единственный способ, который я могу думать, -

a < 0 ? b + a : a % b

Ответ 1

Он ведет себя так, как должен a% b = a - a/b * b; то есть остаток.

Вы можете сделать (a% b + b)% b


Это выражение работает как результат (a % b) обязательно ниже, чем b, независимо от того, является ли a положительным или отрицательным. Добавление b заботится об отрицательных значениях a, так как (a % b) является отрицательным значением между -b и 0, (a % b + b) обязательно ниже, чем b и положительным. Последний modulo существует в случае, когда a был положительным, так как если a положительно (a % b + b) станет больше, чем b. Следовательно, (a % b + b) % b снова превращает его в меньше чем b (и не влияет на отрицательные значения a).

Ответ 2

Начиная с Java 8, вы можете использовать Math.floorMod(int x, int y) и Math.floorMod( long x, long y). Оба этих метода возвращают те же результаты, что и Питер.

Math.floorMod( 2,  3) =  2
Math.floorMod(-2,  3) =  1
Math.floorMod( 2, -3) = -1
Math.floorMod(-2, -3) = -2

Ответ 3

Для тех, кто не использует (или не может использовать) Java 8, Guava пришла на помощь с IntMath.mod(), доступным начиная с Guava 11.0.

IntMath.mod( 2, 3) = 2
IntMath.mod(-2, 3) = 1

Одно предостережение: в отличие от Java 8 Math.floorMod(), делитель (второй параметр) не может быть отрицательным.

Ответ 4

В теории чисел результат всегда положителен. Я бы предположил, что это не всегда происходит на компьютерных языках, потому что не все программисты являются математиками. Мои два цента, я считаю это дефектом дизайна языка, но теперь вы не можете его изменить.

= MOD (-4,180) = 176 = MOD (176, 180) = 176

потому что 180 * (-1) + 176 = -4 то же, что и 180 * 0 + 176 = 176

Используя пример часов здесь, http://mathworld.wolfram.com/Congruence.html вы бы не сказали, что duration_of_time mod cycle_length составляет -45 минут, вы сказали бы 15 минут, хотя оба ответа удовлетворяют базовому уравнению.

Ответ 5

Я предпочитаю это выражение:

a < 0 ? b - (-a) % b : a % b

Это может быть или не быть быстрее, чем другая формула [(a% b + b)% b], подумать об этом. Он содержит ветвь, которая обычно плохо работает с современными процессорами, но использует одну менее модульную операцию.

На самом деле это может быть медленнее.