Какой синтаксис у мода в Java

В качестве примера в псевдокоде:

if ((a mod 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
238
0
962 085
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

Вот представление вашего псевдокода в минимальном Java-коде;

boolean isEven = a % 2 == 0;

Теперь я разобью его на составляющие. Оператор модуля в Java - это символ процента (%). Поэтому взятие int% int возвращает другое int. Оператор двойного равенства (==) используется для сравнения значений, таких как пара целых чисел, и возвращает логическое значение. Затем он присваивается логической переменной isEven. В зависимости от приоритета оператора модуль будет оценен перед сравнением.

минимальный был бы без скобок;)

pstanton 28.09.2010 05:29

Это оператор остатка, а не оператор модуля.

user207421 30.03.2016 04:51

@ user207421 Его имя на самом деле оператор остатка, но разве они не эквивалентны: "модуль - 4. (вычисления, программирование) Оператор, помещенный между двумя числами, чтобы получить остаток от деления этих чисел."?

Gerold Broser 09.05.2019 15:28

Оператор по модулю -% (знак процента). Чтобы проверить на равномерность или вообще по модулю для степени 2, вы также можете использовать & (оператор and), например isEven =! (A & 1).

if (a % 2 == 0) {
} else {
}
Ответ принят как подходящий

Вместо оператора по модулю, имеющего немного другую семантику, для неотрицательных целых чисел вы можете использовать оператор остаток%. Для вашего точного примера:

if ((a % 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}

Это можно упростить до однострочного:

isEven = (a % 2) == 0;

В if / else нет необходимости, просто используйте isEven = (a% 2) == 0,

Steve Kuo 28.07.2010 19:12

Будьте осторожны с терминами модульный и модульный, потому что n (mod m) ВСЕГДА> = 0, но не n% m. n% m находится в диапазоне> -m и <m. Хотя в Java есть оператор остатка для типов int и long, в нем нет функции или оператора модуля. То есть -12% 10 = -2, тогда как -12 mod 10 = 8. Если оператор% возвращает отрицательное значение для n% m, тогда (n% m) + m даст вам n mod m. BigInteger предоставляет функции для обоих, и их спецификации хорошо объясняют разницу. Также осторожно с нулем. В математике, хотя ноль является четным числом, он НЕ является положительным или отрицательным.

Jim 25.08.2012 02:36

почему a % 2 заключен в скобки перед оценкой == 0?

nl-x 03.06.2014 23:09

@ nl-x Вероятно, потому что лучше явно указать приоритет, чем оставить это на усмотрение. Я, например, не знал, что % оценивается до ==, прежде чем я его искал, поэтому было бы неясно, эквивалентно ли выражение (a%2)==0 или a%(2==0). Я думаю, это менее важно в java, где логическое значение не совпадает с целым числом

Matthew Sainsbury 06.06.2014 16:13

Это не оператор модуля - это оператор остатка. Исправьте пожалуйста пост!

Kieren Johnstone 17.07.2015 09:56

логическое даже = ((a & 1) == 0). Намного легче.

mdev 11.03.2018 06:36

Я считаю, что явное if / else проще для глаз и быстрее для сканирования (было бы еще быстрее, если бы открывающие скобки находились в той же строке, что и сигнатуры методов, но, в конце концов, это личное предпочтение). Но мы не всегда должны выбирать «самый короткий», если он снижает удобочитаемость (думая о тернарном вложении операторов).

Wolfone 19.06.2018 09:09

Также мод можно использовать так:

int a = 7;
b = a % 2;

b будет равен 1. Поскольку 7 % 2 = 1.

вероятно, будет ошибкой использовать составные операторы в примере для начинающих и без вывода.

Stu Thompson 18.09.2008 10:48

Альтернатива коду из @Cody:

Используя оператор модуля:

bool isEven = (a % 2) == 0;

Я думаю, что это немного лучший код, чем написание if / else, потому что здесь меньше дублирования и неиспользуемой гибкости. Для изучения требуется немного больше мозгов, но хорошее название isEven компенсирует это.

Это оператор остатка, а не оператор модуля.

user207421 30.03.2016 04:53

@EJP ок. Тогда что такое оператор модуля?

TheRealChx101 20.07.2018 01:29

В Java фактически нет оператора по модулю, как в C. % в Java - оператор остатка. Для положительных целых чисел он работает точно так же, как по модулю, но по-другому работает с отрицательными целыми числами и, в отличие от модуля, может работать и с числами с плавающей запятой. Тем не менее, редко можно использовать% для чего-либо, кроме положительных целых чисел, поэтому, если вы хотите называть это модулем, не стесняйтесь!

Но мне нужен настоящий оператор по модулю, который работает и для отрицательных целых чисел, чтобы array[x mod array.length] всегда обращался к элементу в моем массиве, а не пытался индексировать отрицательные позиции.

Kris 11.11.2019 07:19

(x % y + y) % y или начиная с Java 8, Math.floorMod(x, y)

Greg Charles 12.11.2019 22:11

Поскольку все остальные уже дали ответ, я добавлю немного дополнительного контекста. % оператор "модуля" фактически выполняет остальную операцию. Разница между mod и rem тонкая, но важная.

(-1 mod 2) обычно дает 1. Более конкретно, учитывая два целых числа, X и Y, операция (X mod Y) имеет тенденцию возвращать значение в диапазоне [0, Y). Иными словами, модуль X и Y всегда больше или равен нулю и меньше Y.

Выполнение той же операции с оператором «%» или rem сохраняет знак значения X. Если X отрицательно, вы получите результат в диапазоне (-Y, 0]. Если X положительный, вы получите результат в диапазоне [0, Y).

Часто это тонкое различие не имеет значения. Однако, возвращаясь к вопросу о коде, есть несколько способов решения проблемы «равномерности».

Первый подход хорош для новичков, потому что он особенно многословен.

// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
  isEven = true
}
else
{
  isEven = false
}

Второй подход лучше использует преимущества языка и приводит к более сжатому коду. (Не забывайте, что оператор == возвращает логическое значение.)

// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);

Третий подход здесь для полноты и использует оператор тройной. Хотя тернарный оператор часто бывает очень полезен, в данном случае я считаю второй подход лучшим.

// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;

Четвертый и последний подход - использовать знание двоичное представление целых чисел. Если младший бит равен 0, то число четное. Это можно проверить с помощью побитовый оператор и (&). Хотя этот подход является самым быстрым (вы выполняете простую битовую маскировку вместо деления), он, возможно, немного продвинут / сложен для новичка.

// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);

Здесь я использовал побитовый оператор и и представил его в сжатой форме, показанной в варианте 2. Переписав его в форме варианта 1 (и, как вариант, варианта 3), мы оставляем читателю в качестве упражнения. ;)

Надеюсь, это поможет.

Спасибо, Роб. Эта путаница вызывает огромные трудности в объяснении программистам, как реализовать алгоритмы с математическими свойствами из модульной арифметики. Остаток НЕ является модулем, но можно быстро получить модуль из остатков.

Jim 25.08.2012 02:12

@TickledPink За исключением того, что это не компилируется в Java.

Evgeniy Berezovsky 09.11.2019 04:51

Чтобы заставить Java-операцию% (REM) работать как MOD для отрицательных значений X и положительных Y, вы можете использовать этот метод:

private int mod(int x, int y)
{
    int result = x % y;
    if (result < 0)
    {
        result += y;
    }
    return result;
}

или с тернарным оператором (короче, но невозможно или менее эффективно в некоторых ситуациях):

private int mod(int x, int y)
{
    int result = x % y;
    return result < 0? result + y : result;
}

Оператор остатка в Java - %, а оператор по модулю может быть выражен как

public int mod(int i, int j)
{
  int rem = i % j;
  if (j < 0 && rem > 0)
  {
    return rem + j;
  }
  if (j > 0 && rem < 0)
  {
    return rem + j;
  }
  return rem;
}

Код работает намного быстрее без использования модуля:

public boolean isEven(int a){
    return ( (a & 1) == 0 );
}

public boolean isOdd(int a){
    return ( (a & 1) == 1 );
}

Это выглядит намного чище, чем принятый ответ. Это не имеет ничего общего с преждевременной оптимизацией. Просто лучше, - если это сработает.

AlexWien 15.07.2013 23:39

@LluisMartinez Это одно из самых неправильно цитируемых высказываний в сфере вычислений. Полная цитата такова: «Программисты тратят огромное количество времени на размышления или беспокойство о скорости некритичных частей своих программ, и эти попытки повышения эффективности на самом деле имеют сильное негативное влияние, когда рассматриваются отладка и обслуживание. Мы должны забыть о небольших показатели эффективности говорят о 97% случаев: преждевременная оптимизация - корень всех зол. Тем не менее, мы не должны упускать наши возможности в этих критических 3% ». Что на самом деле означает совсем другое.

user207421 17.11.2015 13:35

@EJP Вы, наверное, правы. Я провел тест (цикл с 1 миллионом итераций) занял 4000 наносекунд с модулем, 2500 наносекунд с логическим и.

Lluis Martinez 18.11.2015 03:43

Почему это был бы ответ? Конечно, он делает нечетное и четное, но ничего не делает с оператором модификации / остатка. Вопрос касается оператора мода, а не того, как найти четное нечетное.

Mark Walsh 24.03.2020 20:30

вам следует изучить спецификацию перед использованием оператора остатка%:

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.17.3

// bad enough implementation of isEven method, for fun. so any worse?
boolean isEven(int num)
{
    num %= 10;
    if (num == 1)
       return false;
    else if (num == 0)
       return true;
    else
       return isEven(num + 2);
}
isEven = isEven(a);

Хотя можно сделать правильный модуль, проверив, является ли значение отрицательным, и скорректировать его, если это так (как многие предлагали), существует более компактное решение.

(a % b + b) % b

Сначала выполняется вычисление по модулю, ограничивая значение диапазоном -b -> + b, а затем добавляется b, чтобы гарантировать, что значение положительное, позволяя следующему модулю ограничить его диапазоном 0 -> b.

Примечание: если b отрицательно, результат также будет отрицательным.

Это может вызвать переполнение, если a и b оба являются большими числами, поэтому это неправильное решение.

Trixie Wolf 12.09.2018 18:49

Другой способ:

boolean isEven = false;
if ((a % 2) == 0)
{
    isEven = true;
}

Но самый простой способ:

boolean isEven = (a % 2) == 0;

Как сказал @Steve Kuo.

В Java это оператор %: 15.17.3. Остающийся оператор%

Обратите внимание, что в классе floorMod также есть java.lang.Math, который даст другой результат, чем %, для аргументов с разными знаками:

public static int floorMod​(int x, int y)

Проголосовали за, потому что floorMod - лучший оператор «по модулю», чем %, так как он также работает правильно, когда аргумент отрицательный. Ни один из других ответов на самом деле не является правильным, поскольку они содержат отказ от ответственности, что% на самом деле не является модулем, если аргументы не являются положительными. В частности, если вы хотите сопоставить каждое целое число с последовательной позицией в массиве, тогда array[floorMod(i, array.length) работает правильно, даже если индекс i переходит на отрицательную территорию. Не так с %.

Kris 11.11.2019 07:23

В Java операция мод может выполняться как таковая:

Math.floorMod(a, b)

Примечание: Операция мод отличается от операции остаток. В Java операция остаток может выполняться как таковая:

a % b

Ну, не совсем ... В javadoc Math.floorMod() есть это: The floor modulus is x - (floorDiv(x, y) * y), has the same sign as the divisor y, and is in the range of -abs(y) < r < +abs(y). Так что это не совсем то же самое, что математический модуль. Но, есть способ получить положительный результат, тоже в Javadoc того же метода: If the signs of arguments are unknown and a positive modulus is needed it can be computed as (floorMod(x, y) + abs(y)) % abs(y).

WesternGun 07.01.2020 01:13

@WesternGun Это может быть правдой, но если вы знаете, что модуль положительный, тогда операция floorMod работает должным образом. Существует также floorMod для значений long и BigInteger для более высоких значений.

Maarten Bodewes 06.05.2020 01:41

Как указывали другие, оператор % (остаток) не совпадает с математическим Операция / функция модуля mod.

mod vs %

The x mod n function maps x to n in the range of [0,n).
Whereas the x % n operator maps x to n in the range of (-n,n).

Чтобы иметь способ использовать операцию математического модуля, а не заботиться о знаке перед x можно:

((x % n) + n) % n

Может быть, эта картинка помогает лучше понять это (мне было трудно сначала осмыслить это)

Хороший рисунок. Еще одна сложность: здесь не учитывается модульность 2 ^ 32 самой переменной int. Метод floorMod делает это правильно (но вам могут потребоваться дополнительные вычисления, если значение n отрицательное).

Maarten Bodewes 06.05.2020 01:44

Другие вопросы по теме