Apa sintaks untuk mod di java


231

Sebagai contoh dalam pseudocode:

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

Jawaban:


357

Alih-alih operator modulo, yang memiliki semantik yang sedikit berbeda, untuk bilangan bulat non-negatif, Anda dapat menggunakan operator sisanya% . Untuk contoh persis Anda:

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

Ini dapat disederhanakan menjadi one-liner:

isEven = (a % 2) == 0;

80
Jika / tidak diperlukan, cukup gunakan isEven = (a% 2) == 0,
Steve Kuo

59
Hati-hati dengan istilah mod dan modular karena n (mod m) SELALU> = 0 tetapi tidak n% m. n% m dalam kisaran> -m dan <m. Walaupun Java memiliki operator sisa untuk tipe int dan panjang, Java tidak memiliki fungsi modulus atau operator. Yaitu, -12% 10 = -2 sedangkan -12 mod 10 = 8. Jika% operator mengembalikan nilai negatif untuk n% m, maka (n% m) + m akan memberi Anda n mod m. BigInteger menyediakan fungsi untuk keduanya dan spesifikasi untuk mereka menjelaskan perbedaannya dengan cukup baik. Juga, berhati-hatilah dengan nol. Dalam matematika, sementara nol adalah bilangan genap, BUKAN positif atau negatif.
Jim

4
@ nl-x Mungkin karena lebih baik secara eksplisit tentang prioritas daripada menyerahkannya pada konvensi. Saya tidak tahu yang %dievaluasi sebelum ==saya mencarinya, jadi tidak jelas apakah ekspresi itu setara (a%2)==0atau a%(2==0). Saya kira itu kurang penting di java di mana boolean tidak sama dengan bilangan bulat
Matthew Sainsbury

8
Ini bukan operator modulus - ini adalah operator sisanya. Harap perbaiki pos!
Kieren Johnstone

2
boolean even = ((a & 1) == 0). Jauh lebih mudah.
mdev

111

Berikut ini adalah representasi kode semu Anda dalam kode Java minimal;

boolean isEven = a % 2 == 0;

Sekarang saya akan memecahnya menjadi komponen-komponennya. Operator modulus di Jawa adalah karakter persen (%). Oleh karena itu mengambil int% int mengembalikan int lain. Operator double equals (==) digunakan untuk membandingkan nilai, seperti sepasang int dan mengembalikan boolean. Ini kemudian ditugaskan ke variabel boolean 'isEven'. Berdasarkan prioritas operator modulus akan dievaluasi sebelum perbandingan.


12
minimal akan tanpa tanda kurung;)
pstanton

3
Ini adalah operator sisa, bukan operator modulus.
Marquis dari Lorne

@ user207421 Namanya sebenarnya operator sisa tetapi bukankah mereka setara: " modulus - 4. (komputasi, pemrograman) Seorang operator ditempatkan di antara dua angka, untuk mendapatkan sisa pembagian angka-angka itu."?
GeroldBroser mengembalikan Monica

93

Karena semua orang sudah memberikan jawabannya, saya akan menambahkan sedikit konteks tambahan. % "modulus" operator sebenarnya melakukan operasi sisanya. Perbedaan antara mod dan rem halus, tetapi penting.

(-1 mod 2) biasanya akan memberikan 1. Lebih khusus diberikan dua bilangan bulat, X dan Y, operasi (X mod Y) cenderung mengembalikan nilai dalam kisaran [0, Y). Dikatakan berbeda, modulus X dan Y selalu lebih besar dari atau sama dengan nol, dan kurang dari Y.

Melakukan operasi yang sama dengan "%" atau operator rem mempertahankan tanda nilai X. Jika X negatif Anda mendapatkan hasil dalam rentang (-Y, 0). Jika X positif Anda mendapatkan hasil dalam kisaran [0, Y).

Seringkali perbedaan halus ini tidak masalah. Kembali ke pertanyaan kode Anda, ada beberapa cara penyelesaian untuk "evenness".

Pendekatan pertama baik untuk pemula, karena sangat bertele-tele.

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

Pendekatan kedua mengambil keuntungan lebih baik dari bahasa tersebut, dan mengarah pada kode yang lebih ringkas. (Jangan lupa bahwa operator == mengembalikan boolean.)

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

Pendekatan ketiga di sini untuk kelengkapan, dan menggunakan operator ternary . Meskipun operator ternary sering sangat berguna, dalam hal ini saya menganggap pendekatan kedua lebih unggul.

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

Pendekatan keempat dan terakhir adalah menggunakan pengetahuan tentang representasi biner dari bilangan bulat . Jika bit paling signifikan adalah 0 maka angkanya genap. Ini dapat diperiksa menggunakan bitwise-and operator (&). Meskipun pendekatan ini adalah yang tercepat (Anda melakukan penyembunyian bit sederhana alih-alih pembagian), mungkin ini sedikit maju / rumit untuk pemula.

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

Di sini saya menggunakan bitwise-dan operator, dan mewakilinya dalam bentuk ringkas yang ditunjukkan pada opsi 2. Menulis ulang dalam bentuk Opsi 1 (dan sebagai alternatif Opsi 3) dibiarkan sebagai latihan untuk pembaca. ;)

Semoga itu bisa membantu.


Rob terima kasih. Kebingungan ini menyebabkan kesulitan besar dalam menjelaskan kepada programmer bagaimana menerapkan algoritma dengan sifat matematika dari aritmatika modular. Sisa BUKAN modulus tetapi orang dapat dengan cepat memperoleh modulus dari sisanya.
Jim

1
@TickledPink Kecuali ini tidak dikompilasi di Java.
Eugene Beresovsky

33

Untuk menjalankan operasi% (REM) Java seperti MOD untuk nilai X negatif dan Y positif, Anda dapat menggunakan metode ini:

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

atau dengan operator ternary (lebih pendek, tetapi tidak mungkin atau kurang efisien dalam beberapa situasi):

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

12

Java sebenarnya tidak memiliki operator modulo seperti C. % di Jawa adalah operator sisanya. Pada bilangan bulat positif, ia bekerja persis seperti modulo, tetapi ia bekerja secara berbeda pada bilangan bulat negatif dan, tidak seperti modulo, dapat bekerja dengan angka floating point juga. Namun, jarang menggunakan% pada apa pun kecuali bilangan bulat positif, jadi jika Anda ingin menyebutnya modulo, silakan saja!


Tapi saya ingin satu operator modulo nyata yang bekerja untuk bilangan bulat negatif juga sehingga selalu array[x mod array.length]mengakses elemen dalam array saya daripada mencoba untuk mengindeks posisi negatif.
Kris

2
(x % y + y) % y atau mulai di Jawa 8,Math.floorMod(x, y)
Greg Charles

12

Meskipun dimungkinkan untuk melakukan modulo yang tepat dengan memeriksa apakah nilainya negatif dan memperbaikinya jika itu (cara yang disarankan banyak orang), ada solusi yang lebih kompak.

(a % b + b) % b

Ini pertama-tama akan melakukan modulo, membatasi nilai ke -b -> + b dan kemudian menambahkan b untuk memastikan bahwa nilainya positif, membiarkan modulo berikutnya membatasi ke kisaran 0 -> b.

Catatan: Jika b negatif, hasilnya juga akan negatif


Ini bisa meluap ketika a dan b keduanya angka besar, jadi itu bukan solusi yang benar.
Trixie Wolf

11

Kode berjalan lebih cepat tanpa menggunakan modulo:

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

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

3
Ini terlihat jauh lebih bersih daripada jawaban yang diterima. Ini tidak ada hubungannya dengan optimasi prematur. Ini lebih baik, - jika berhasil.
AlexWien

4
@LluisMartinez Ini adalah salah satu ucapan yang paling salah kutip dalam komputasi. Kutipan lengkapnya adalah "Programmer menghabiskan banyak waktu memikirkan, atau mengkhawatirkan, kecepatan bagian nonkritis dari program mereka, dan upaya efisiensi ini sebenarnya memiliki dampak negatif yang kuat ketika debugging dan pemeliharaan dipertimbangkan. Kita harus melupakan sedikit efisiensi, katakanlah sekitar 97% dari waktu: optimasi prematur adalah akar dari semua kejahatan. Namun kita tidak boleh melewatkan peluang kita dalam 3% kritis itu. " Yang sebenarnya berarti sesuatu yang sangat berbeda.
Marquis of Lorne

3
@ EJP Anda mungkin benar. Saya melakukan tes (loop dengan 1 juta iterasi) mengambil 4000 nanodetik dengan modulo, 2500 nanodetik dengan logika dan.
Lluis Martinez

Mengapa ini menjadi jawaban? Tentu itu memang aneh bahkan, tetapi tidak melakukan apa pun dengan mod / operator sisa. Pertanyaannya berbicara tentang operator mod, bukan bagaimana menemukan aneh.
Mark Walsh



4

Di Jawa itu adalah %operator: 15.17.3. Operator Sisa%

Perhatikan bahwa ada juga floorModdi java.lang.Mathkelas yang akan memberikan hasil yang berbeda dari %argumen dengan tanda yang berbeda:

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


1
Terpilih, karena floorMod adalah operator 'modulo' yang lebih baik daripada %karena itu juga berfungsi dengan baik ketika argumennya negatif juga. Tidak ada jawaban lain yang benar karena mereka datang dengan penafian bahwa% tidak benar-benar modulo kecuali argumennya positif. Khususnya jika Anda ingin memetakan setiap bilangan bulat ke posisi berurutan dalam sebuah array maka array[floorMod(i, array.length)berfungsi dengan benar bahkan jika indeks imasuk ke wilayah negatif. Tidak demikian halnya dengan %.
Kris

3

Selain itu, mod dapat digunakan seperti ini:

int a = 7;
b = a % 2;

bakan sama dengan 1. Karena 7 % 2 = 1.


mungkin merupakan kesalahan untuk menggunakan operator gabungan dalam contoh untuk pemula, dan tanpa output.
Stu Thompson

3

Operator sisanya di Jawa adalah %dan operator modulo dapat dinyatakan sebagai

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

Seperti yang telah ditunjukkan orang lain, %operator (sisa) tidak sama dengan modoperasi / fungsi modulus matematika .

mod vs. %

The x mod nfungsi peta xuntuk ndi kisaran [0,n).
Sedangkan x % nOperator peta xuntuk ndi kisaran (-n,n).

Agar memiliki metode untuk menggunakan operasi modulus matematika dan tidak peduli dengan tanda di depan xorang dapat menggunakan:

((x % n) + n) % n

Mungkin gambar ini membantu memahaminya dengan lebih baik (saya kesulitan membungkus kepala saya dulu)

masukkan deskripsi gambar di sini


1
Lukisan yang bagus. Satu kompleksitas lainnya: ini tidak memperhitungkan modularitas 2 ^ 32 dari intvariabel itu sendiri. The floorModmetode tidak melakukan itu dengan benar (tetapi Anda mungkin perlu perhitungan tambahan jika nnegatif).
Maarten Bodewes

1

Cara lain adalah:

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

Namun cara termudah masih:

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

Seperti yang dikatakan @Steve Kuo.


0

Dalam Java, operasi mod dapat dilakukan seperti itu:

Math.floorMod(a, b)

Catatan: The mod operasi berbeda dari sisa operasi. Dalam Java, operasi sisanya dapat dilakukan seperti:

a % b

Yah tidak persis ... Javadoc Math.floorMod()memilikinya: 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).Jadi tidak persis sama dengan modulus matematika. Tapi , ada cara untuk mendapatkan hasil positif, juga di Javadoc dengan metode yang sama: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 Itu mungkin benar, tetapi jika Anda tahu bahwa modulus positif maka floorModoperasi berfungsi seperti yang diharapkan. Ada juga floorModuntuk longnilai dan sebaliknya ada BigIntegeruntuk nilai yang lebih besar.
Maarten Bodewes

-1

Operator modulo adalah% (tanda persen). Untuk menguji kemerataan atau secara umum melakukan modulo untuk kekuatan 2, Anda juga dapat menggunakan & (operator dan) seperti isEven =! (A & 1).


-3

Alternatif kode dari @Cody:

Menggunakan operator modulus:

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

Saya pikir ini adalah kode yang sedikit lebih baik daripada menulis if / else, karena ada sedikit duplikasi & fleksibilitas yang tidak digunakan. Memang membutuhkan sedikit lebih banyak kekuatan otak untuk memeriksanya, tetapi pemberian nama yang bagus sebagai isEvenkompensasi.


2
Ini adalah operator sisa, bukan operator modulus.
Marquis of Lorne

@ EJP ok. Lalu apa operator modulus?
TheRealChx101
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.