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

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

a % b 

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

 a < 0 ? b + a : a % b 

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

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


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

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

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

    = 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-1 - (-a-1) % b : a % b 

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

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

    (Изменить: Исправлена ​​формула.)

    Interesting Posts

    Что я могу сделать, чтобы остановить кнопку Play / Pause от открытия iTunes?

    Как я могу запретить Visual Studio 2013 закрывать приложение IIS Express при завершении отладки?

    Windows 8: Как закрыть (не спать) ноутбук на крышке близко?

    Как объединить список списков с одинаковыми типами элементов в один список элементов?

    Как преобразовать этот список словарей в файл csv?

    Установка DataContext в XAML в WPF

    В чем разница между ‘int?’ и ‘int’ в C #?

    Привязать к переменной массива bash косвенно, динамически сконструированным именем переменной

    Сравнить файлы с контрольной суммой по отношению друг к другу?

    Установка SparkR

    С явно удаленными функциями-членами в C ++ 11, стоит ли наследовать от неготовного базового classа?

    Неправильная специализированная функция генерируется в Swift 3 по косвенному вызову

    Разница между `% in%` и `==`

    Обработка ошибок с помощью адаптера (теперь по умолчанию) Ember Data JSON-API

    Пересечение и объединение ArrayLists в Java

    Давайте будем гением компьютера.