Який синтаксис мода в java


231

Як приклад у псевдокоді:

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

Відповіді:


357

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

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

Це можна спростити до однолінійного:

isEven = (a % 2) == 0;

80
Якщо if / else непотрібне, просто використовуйте isEven = (a% 2) == 0,
Стів Куо

59
Обережно з термінами mod та modular тому, що 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 надає функції для обох, а технічні характеристики для них досить добре пояснюють різницю. Також обережно з нулем. У математиці, хоча нуль є парним числом, воно НЕ є позитивним чи негативним.
Джим

4
@ nl-x Мабуть тому, що краще бути явним щодо пріоритету, ніж залишати це умовно. Я для одного не знав, що %оцінюється раніше, перш ==ніж я його подивився, тому було б незрозуміло, чи вираз еквівалентний (a%2)==0або a%(2==0). Я думаю, що менш важливо в Java, де булевий не такий, як ціле число
Matthew Sainsbury

8
Це не оператор модуля - це решта оператора. Будь ласка, виправте повідомлення!
Кірен Джонстон

2
булева рівномірність = ((a & 1) == 0). Набагато простіше.
mdev

111

Ось представлення вашого псевдо-коду в мінімальному коді Java;

boolean isEven = a % 2 == 0;

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


12
мінімальна була б без дужок;)
pstanton

3
Це залишок оператора, а не оператор модуля.
Маркіз Лорн

@ user207421 Насправді його ім'я є оператором залишку, але чи не вони еквівалентні: " модуль - 4. (обчислення, програмування) Оператор, розміщений між двома числами, щоб отримати залишок ділення цих чисел."
ГерольдБрозер повертає Моніку

93

Оскільки всі інші вже дали відповідь, я додам трохи додаткового контексту. % оператор "modulus" фактично виконує решту операцій. Різниця між модом та ремом є тонкою, але важливою.

(-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) залишається читачем як вправа. ;)

Сподіваюся, що це допомагає.


Дякую Роб. Ця плутанина викликає величезні труднощі в поясненні програмістам, як реалізувати алгоритми з математичними властивостями з модульної арифметики. Залишок НЕ є модулем, але можна швидко отримати модуль з залишків.
Джим

1
@TickledPink За винятком того, що це не компілюється в Java.
Євген

33

Щоб заставити операцію 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;
}

12

Java насправді не має оператора модуля, як це робить C. % в Java - оператор залишку. На позитивних цілих числах він працює точно так само, як і модуль, але він діє по-різному на негативних цілих чисел і, на відміну від модуля, може працювати і з числами з плаваючою комою. Тим не менш, рідко використовувати% для будь-якого, крім позитивних цілих чисел, тому, якщо ви хочете назвати це модулем, тоді не соромтеся!


Але я хочу, щоб він був справжнім оператором модуля, який також працює для негативних цілих чисел, щоб array[x mod array.length]завжди отримувати доступ до елемента в моєму масиві, а не намагатися індексувати негативні позиції.
Кріс

2
(x % y + y) % y або починаючи з Java 8,Math.floorMod(x, y)
Грег Чарльз

12

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

(a % b + b) % b

Це спочатку зробить модуль, обмеживши значення діапазоном -b -> + b, а потім додавши b, щоб переконатися, що значення є позитивним, дозволяючи наступному модулю обмежити його діапазоном 0 -> b.

Примітка: Якщо b від'ємний, результат також буде негативним


Це може переповнюватися, коли а і b є великими числами, тому це не є правильним рішенням.
Trixie Wolf

11

Код працює набагато швидше, не використовуючи модуль:

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

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

3
Це виглядає набагато чіткіше, ніж прийнята відповідь. Це не має нічого спільного з передчасною оптимізацією. Просто краще, - якщо це працює.
AlexWien

4
@LluisMartinez Це одне з найбільш часто цитуваних приказок в обчислювальній техніці. Повна цитата: "Програмісти витрачають величезну кількість часу на роздуми або переживаючи про швидкість некритичних частин своїх програм, і ці спроби ефективності насправді мають сильний негативний вплив при розгляді налагодження та обслуговування. Ми повинні забути про невеликі ефективність, говорять про 97% часу: передчасна оптимізація - корінь усього зла. Але ми не повинні передавати свої можливості на критичних 3%. " Що насправді означає щось зовсім інше.
Маркіз Лорн

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

Чому це було б відповіддю? Звичайно, це не дивно, але нічого не робить з оператором mod / залишок. Питання говорить про мод оператора, а не про те, як знайти непарні парні.
Марк Уолш



4

У Java це %оператор: 15.17.3. Оператор залишку%

Зауважте, що floorModв java.lang.Mathкласі також є результат, який дасть різний результат %для аргументів з різними ознаками:

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


1
Оновлено, тому що floorMod є кращим "модульним" оператором, ніж %він також працює належним чином, коли аргумент також негативний. Жоден з інших відповідей насправді не є правильним, оскільки він приходить з відмовою від відповідальності, що% насправді не є модулем, якщо аргументи не є позитивними. Зокрема, якщо ви хочете зіставити кожне ціле число на послідовну позицію в масиві, тоді воно array[floorMod(i, array.length)працює правильно, навіть якщо індекс iпереходить у негативну територію. Не так з %.
Кріс

3

Також мод можна використовувати так:

int a = 7;
b = a % 2;

bдорівнювали б 1. Тому що 7 % 2 = 1.


це, мабуть, помилка використовувати складні оператори в прикладі для початківців, і без виходу.
Стю Томпсон

3

Оператор, що залишився в 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;
}

2

Як зазначали %інші, оператор (залишок) - це не те саме, що modфункціонування / функція математичного модуля.

mod проти %

x mod nФункція відображає xна nв діапазоні [0,n).
У той час як x % nоператор переводить xдо nв діапазоні (-n,n).

Для того, щоб мати метод використання операції математичного модуля і не піклуватися про знак перед ним, xможна використовувати:

((x % n) + n) % n

Можливо, ця картина допомагає зрозуміти її краще (мені важко було обернути голову навколо цього першого)

введіть тут опис зображення


1
Гарний малюнок. Ще одна складність: це не враховує 2 ^ 32 модульність самої intзмінної. floorModМетод не робить це правильно (але вам можуть знадобитися додаткові розрахунки , якщо nнегативна).
Maarten Bodewes

1

Ще один спосіб:

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

Але найпростіший спосіб все-таки:

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

Як сказав @Steve Kuo


0

В Java, то мод операція може бути виконана , наприклад , як:

Math.floorMod(a, b)

Примітка: Операція моди відрізняється від решти операції. В Java, то залишилася операція може бути виконана , наприклад , як:

a % b

Ну не зовсім ... Явадок цього 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

@WesternGun Це може бути правдою, але якщо ви знаєте, що модуль позитивний, то floorModоперація працює як очікувалося. Існує також значення floorModдля longзначень, інакше існує BigIntegerдля більших значень.
Maarten Bodewes

-1

Оператор модуля -% (знак відсотка). Щоб перевірити рівномірність або взагалі зробити модуль на потужність 2, ви також можете використовувати & (і оператор), як isEven =! (A & 1).


-3

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

Використання оператора модуля:

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

Я думаю, що це незначно кращий код, ніж писати if / else, оскільки там менше дублювання та невикористаної гнучкості. Це вимагає трохи більше сил для вивчення мозку, але добре називання isEvenкомпенсує.


2
Це залишок оператора, а не оператор модуля.
Маркіз Лорн

@EJP добре. Тоді що таке оператор модуля?
TheRealChx101
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.