В java, когда вы делаете
a % b
Если a отрицательно, он вернет отрицательный результат, вместо того, чтобы обертывать его так, как нужно. Какой лучший способ исправить это? Единственный способ, который я могу думать, -
a < 0 ? b + a : a % b
В java, когда вы делаете
a % b
Если a отрицательно, он вернет отрицательный результат, вместо того, чтобы обертывать его так, как нужно. Какой лучший способ исправить это? Единственный способ, который я могу думать, -
a < 0 ? b + a : a % b
Он ведет себя так, как должен 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
).
Начиная с 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
Для тех, кто не использует (или не может использовать) Java 8, Guava пришла на помощь с IntMath.mod(), доступным начиная с Guava 11.0.
IntMath.mod( 2, 3) = 2
IntMath.mod(-2, 3) = 1
Одно предостережение: в отличие от Java 8 Math.floorMod(), делитель (второй параметр) не может быть отрицательным.
В теории чисел результат всегда положителен. Я бы предположил, что это не всегда происходит на компьютерных языках, потому что не все программисты являются математиками. Мои два цента, я считаю это дефектом дизайна языка, но теперь вы не можете его изменить.
= 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 минут, хотя оба ответа удовлетворяют базовому уравнению.
Я предпочитаю это выражение:
a < 0 ? b - (-a) % b : a % b
Это может быть или не быть быстрее, чем другая формула [(a% b + b)% b], подумать об этом. Он содержит ветвь, которая обычно плохо работает с современными процессорами, но использует одну менее модульную операцию.
На самом деле это может быть медленнее.