Odpowiedzi:
Zamiast operatora modulo, który ma nieco inną semantykę, dla liczb całkowitych nieujemnych można użyć operatora reszty%
. Dla twojego dokładnego przykładu:
if ((a % 2) == 0)
{
isEven = true;
}
else
{
isEven = false;
}
Można to uprościć do jednej linijki:
isEven = (a % 2) == 0;
%
jest to oceniane przed sprawdzeniem ==
go, więc nie byłoby jasne, czy wyrażenie jest równoważne (a%2)==0
czy a%(2==0)
. Myślę, że to mniej ważne w Javie, gdzie wartość logiczna to nie to samo, co liczba całkowita
Oto reprezentacja twojego pseudo-kodu w minimalnym kodzie Java;
boolean isEven = a % 2 == 0;
Teraz podzielę go na części. Operatorem modułu w Javie jest znak procentu (%). Dlatego przyjęcie int% int zwraca inną int. Operator double equals (==) służy do porównywania wartości, takich jak para liczb całkowitych i zwraca wartość logiczną. Jest to następnie przypisywane do zmiennej boolowskiej „isEven”. W oparciu o pierwszeństwo operatora moduł zostanie oceniony przed porównaniem.
Ponieważ wszyscy inni już udzielili odpowiedzi, dodam trochę dodatkowego kontekstu. % operator „modułu” faktycznie wykonuje pozostałą operację. Różnica między modem a remem jest subtelna, ale ważna.
(-1 mod 2) normalnie dałoby 1. Dokładniej biorąc pod uwagę dwie liczby całkowite, X i Y, operacja (X mod Y) zwraca wartość z zakresu [0, Y). Inaczej mówiąc, moduł X i Y jest zawsze większy lub równy zero i mniejszy niż Y.
Wykonywanie tej samej operacji za pomocą operatora „%” lub rem utrzymuje znak wartości X. Jeśli X jest ujemne, otrzymujesz wynik w zakresie (-Y, 0). Jeśli X jest dodatni, otrzymujesz wynik w zakresie [0, Y).
Często to subtelne rozróżnienie nie ma znaczenia. Wracając do pytania o kod, istnieje wiele sposobów rozwiązania „równości”.
Pierwsze podejście jest dobre dla początkujących, ponieważ jest szczególnie szczegółowe.
// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
isEven = true
}
else
{
isEven = false
}
Drugie podejście lepiej wykorzystuje język i prowadzi do bardziej zwięzłego kodu. (Nie zapominaj, że operator == zwraca wartość logiczną).
// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);
Trzecie podejście jest tutaj dla kompletności i wykorzystuje operator trójskładnikowy . Chociaż operator trójskładnikowy jest często bardzo przydatny, w tym przypadku uważam, że drugie podejście jest lepsze.
// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;
Czwarte i ostatnie podejście polega na wykorzystaniu wiedzy o binarnej reprezentacji liczb całkowitych . Jeśli najmniej znaczącym bitem jest 0, liczba jest parzysta. Można to sprawdzić za pomocą operatora bitowego i operatora (&). Chociaż takie podejście jest najszybsze (wykonujesz proste maskowanie bitów zamiast dzielenia), być może jest trochę zaawansowane / skomplikowane dla początkującego.
// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);
Tutaj użyłem operatora bitowego i operatora i przedstawiłem go w zwięzłej formie pokazanej w opcji 2. Przepisanie go w formie opcji 1 (i alternatywnie opcji 3) pozostawia się jako ćwiczenie dla czytelnika. ;)
Mam nadzieję, że to pomaga.
Aby operacja% (REM) Java działała jak MOD dla ujemnych wartości X i dodatnich wartości Y, możesz użyć tej metody:
private int mod(int x, int y)
{
int result = x % y;
if (result < 0)
{
result += y;
}
return result;
}
lub z operatorem trójskładnikowym (krótszy, ale w niektórych sytuacjach niemożliwy lub mniej wydajny):
private int mod(int x, int y)
{
int result = x % y;
return result < 0? result + y : result;
}
Java faktycznie nie ma operatora modulo, podobnie jak C. % w Javie jest operatorem reszty. Na dodatnich liczbach całkowitych działa dokładnie tak jak modulo, ale działa inaczej na ujemnych liczbach całkowitych i, w przeciwieństwie do modulo, może również pracować z liczbami zmiennoprzecinkowymi. Nadal jednak rzadko używa się% na liczbach całkowitych innych niż dodatnie, więc jeśli chcesz nazwać to modulo, nie krępuj się!
array[x mod array.length]
zawsze miał dostęp do elementu w mojej tablicy, zamiast próbować indeksować ujemne pozycje.
(x % y + y) % y
lub począwszy od Java 8,Math.floorMod(x, y)
Chociaż możliwe jest wykonanie właściwego modulo poprzez sprawdzenie, czy wartość jest ujemna i poprawienie, jeśli tak jest (jak sugerowało wielu), istnieje bardziej zwarte rozwiązanie.
(a % b + b) % b
To najpierw zrobi modulo, ograniczając wartość do zakresu -b -> + b, a następnie doda b, aby upewnić się, że wartość jest dodatnia, pozwalając następnemu modulo ograniczyć ją do zakresu 0 -> b.
Uwaga: Jeśli b jest ujemne, wynik również będzie ujemny
Kod działa znacznie szybciej bez użycia modulo:
public boolean isEven(int a){
return ( (a & 1) == 0 );
}
public boolean isOdd(int a){
return ( (a & 1) == 1 );
}
przed użyciem operatora „resztki”% należy sprawdzić specyfikację:
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);
W Javie jest to %
operator:
15.17.3. Pozostały operator%
Należy pamiętać, że istnieje również floorMod
w java.lang.Math
klasie, która da inny wynik z %
argumentów z różnych znaków:
%
działa również poprawnie, gdy argument jest również ujemny. Żadna z pozostałych odpowiedzi tak naprawdę nie jest poprawna, ponieważ zawierają zastrzeżenie, że% nie jest tak naprawdę modulo, chyba że argumenty są pozytywne. W szczególności, jeśli chcesz zmapować każdą liczbę całkowitą na kolejną pozycję w tablicy, to array[floorMod(i, array.length)
działa poprawnie, nawet jeśli indeks i
przechodzi na terytorium ujemne. Nie tak z %
.
Również mod może być użyty w ten sposób:
int a = 7;
b = a % 2;
b
byłoby równe 1. Ponieważ 7 % 2 = 1
.
Jak zauważyli inni, %
operator (reszta) nie jest tym samym co mod
operacja / funkcja modułu matematycznego
.
mod
vs%
x mod n
Funkcja odwzorowujex
sięn
w przedziale[0,n)
.
Natomiastx % n
operator odwzorowujex
sięn
w przedziale(-n,n)
.
Aby mieć metodę korzystania z operacji modułu matematycznego i nie dbać o znak przed x
jednym, można użyć:
((x % n) + n) % n
Może to zdjęcie pomaga lepiej to zrozumieć (ciężko mi było owinąć głowę tym pierwszym)
int
samej zmiennej 2 ^ 32 . floorMod
Metoda robi to poprawnie (ale być może trzeba dodatkowych obliczeń, jeśli n
jest ujemna).
W Java
trybie mod można wykonać jako taki:
Math.floorMod(a, b)
Uwaga:
Operacja mod różni się od operacji reszty . W Java
The pozostała operacja może być przeprowadzona w następujący sposób:
a % b
Math.floorMod()
ma to: 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).
więc nie jest dokładnie taki sam jak moduł matematyczny. Ale istnieje sposób na uzyskanie pozytywnego wyniku, również w Javadoc tej samej metody: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).
floorMod
operacja działa zgodnie z oczekiwaniami. Istnieją również wartości floorMod
for long
, a poza tym BigInteger
wartości większe.
Alternatywa dla kodu z @Cody:
Za pomocą operatora modułu:
bool isEven = (a % 2) == 0;
Myślę, że jest to nieznacznie lepszy kod niż pisanie if / else, ponieważ jest mniej powielania i nieużywana elastyczność. Badanie wymaga nieco więcej mocy mózgu, ale dobre nazewnictwo isEven
kompensuje.