Cú pháp cho mod trong java là gì


231

Như một ví dụ trong mã giả:

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

Câu trả lời:


357

Thay vì toán tử modulo, có ngữ nghĩa hơi khác nhau, đối với các số nguyên không âm, bạn có thể sử dụng toán tử còn lại% . Ví dụ chính xác của bạn:

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

Điều này có thể được đơn giản hóa thành một lớp lót:

isEven = (a % 2) == 0;

80
Nếu / khác là không cần thiết, chỉ cần sử dụng isEven = (a% 2) == 0,
Steve Kuo

59
Cẩn thận với các điều khoản mod và mô-đun vì n (mod m) LUÔN LUÔN> = 0 nhưng không phải n% m. n% m nằm trong phạm vi> -m và <m. Mặc dù Java có toán tử còn lại cho các kiểu int và long, nhưng nó không có hàm mô đun hoặc toán tử. Tức là, -12% 10 = -2 trong khi -12 mod 10 = 8. Nếu% toán tử trả về giá trị âm cho n% m, thì (n% m) + m sẽ cung cấp cho bạn n mod m. BigInteger cung cấp các chức năng cho cả hai và các thông số kỹ thuật cho chúng giải thích sự khác biệt khá tốt. Ngoài ra, cẩn thận với số không. Trong toán học, trong khi số 0 là số chẵn thì nó KHÔNG dương hoặc âm.
Jim

4
@ nl-x Có lẽ bởi vì tốt hơn là nên rõ ràng về quyền ưu tiên hơn là để nó theo quy ước. Tôi cho một người không biết rằng đã %được đánh giá trước ==khi tôi tra cứu nó, vì vậy sẽ không rõ liệu biểu thức đó có tương đương với (a%2)==0hay không a%(2==0). Tôi đoán nó ít quan trọng hơn trong java khi boolean không giống với số nguyên
Matthew Sainsbury

8
Đây không phải là toán tử mô đun - nó là toán tử còn lại. Hãy sửa bài!
Kieren Johnstone

2
boolean chẵn = ((a & 1) == 0). Dễ dàng hơn nhiều.
mdev

111

Đây là cách trình bày mã giả của bạn trong mã Java tối thiểu;

boolean isEven = a % 2 == 0;

Bây giờ tôi sẽ chia nó thành các thành phần của nó. Toán tử mô đun trong Java là ký tự phần trăm (%). Do đó, lấy một int% int trả về một int khác. Toán tử double bằng (==) được sử dụng để so sánh các giá trị, chẳng hạn như một cặp số nguyên và trả về một giá trị boolean. Điều này sau đó được gán cho biến boolean 'isEven'. Dựa trên ưu tiên toán tử, mô đun sẽ được đánh giá trước khi so sánh.


12
tối thiểu sẽ không có dấu ngoặc;)
pstanton

3
Đó là toán tử còn lại, không phải toán tử mô đun.
Hầu tước Lorne

@ user207421 Tên của nó trong thực tế là toán tử còn lại nhưng không tương đương nhau: " modulus - 4. (tính toán, lập trình) Một toán tử được đặt giữa hai số, để lấy phần còn lại của các số đó."?
GeroldBroser phục hồi Monica

93

Vì mọi người khác đã đưa ra câu trả lời, tôi sẽ thêm một chút bối cảnh bổ sung. % toán tử "mô-đun" thực sự đang thực hiện thao tác còn lại. Sự khác biệt giữa mod và rem là tinh tế, nhưng quan trọng.

(-1 mod 2) thường sẽ cung cấp 1. Cụ thể hơn, hai số nguyên X và Y, hoạt động (X mod Y) có xu hướng trả về một giá trị trong phạm vi [0, Y). Nói cách khác, mô đun của X và Y luôn lớn hơn hoặc bằng 0 và nhỏ hơn Y.

Thực hiện cùng một hoạt động với "%" hoặc toán tử rem duy trì dấu của giá trị X. Nếu X âm, bạn nhận được kết quả trong phạm vi (-Y, 0]. Nếu X dương, bạn nhận được kết quả trong phạm vi [0, Y).

Thường thì sự phân biệt tinh tế này không thành vấn đề. Quay trở lại câu hỏi mã của bạn, tuy nhiên, có nhiều cách giải quyết cho "sự đồng đều".

Cách tiếp cận đầu tiên là tốt cho người mới bắt đầu, bởi vì nó đặc biệt dài dòng.

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

Cách tiếp cận thứ hai tận dụng lợi thế của ngôn ngữ tốt hơn và dẫn đến mã ngắn gọn hơn. (Đừng quên rằng toán tử == trả về boolean.)

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

Cách tiếp cận thứ ba là ở đây để hoàn thiện và sử dụng toán tử ternary . Mặc dù toán tử ternary thường rất hữu ích, nhưng trong trường hợp này tôi coi cách tiếp cận thứ hai là vượt trội.

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

Cách tiếp cận thứ tư và cuối cùng là sử dụng kiến ​​thức về biểu diễn nhị phân của số nguyên . Nếu bit có ý nghĩa nhỏ nhất là 0 thì số đó là số chẵn. Điều này có thể được kiểm tra bằng bitwise - và toán tử (&). Mặc dù cách tiếp cận này là nhanh nhất (bạn đang thực hiện mặt nạ bit đơn giản thay vì chia), nhưng có lẽ nó hơi tiên tiến / phức tạp đối với người mới bắt đầu.

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

Ở đây tôi đã sử dụng toán tử bitwise và toán tử, và biểu diễn nó ở dạng cô đọng được hiển thị trong tùy chọn 2. Viết lại nó ở dạng của Tùy chọn 1 (và thay vào đó là Tùy chọn 3) để lại cho người đọc. ;)

Mong rằng sẽ giúp.


Cảm ơn bạn Rob. Sự nhầm lẫn này gây ra những khó khăn to lớn trong việc giải thích cho các lập trình viên cách thực hiện các thuật toán với các thuộc tính toán học từ số học mô-đun. Phần còn lại KHÔNG phải là mô-đun nhưng người ta có thể nhanh chóng rút ra một mô-đun từ phần còn lại.
Jim

1
@TickledPink Ngoại trừ việc này không biên dịch trong Java.
Eugene Beresovsky

33

Để làm cho hoạt động% (REM) của Java hoạt động như MOD cho các giá trị X âm và Y dương, bạn có thể sử dụng phương thức này:

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

hoặc với toán tử ternary (ngắn hơn, nhưng không thể hoặc kém hiệu quả hơn trong một số trường hợp):

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

12

Java thực sự không có toán tử modulo theo cách C làm. % trong Java là toán tử còn lại. Trên các số nguyên dương, nó hoạt động chính xác như modulo, nhưng nó hoạt động khác với các số nguyên âm và, không giống như modulo, cũng có thể hoạt động với các số dấu phẩy động. Tuy nhiên, thật hiếm khi sử dụng% cho bất cứ thứ gì ngoại trừ số nguyên dương, vì vậy nếu bạn muốn gọi nó là modulo, thì cứ thoải mái!


Nhưng tôi muốn một toán tử modulo thực sự cũng hoạt động cho các số nguyên âm để array[x mod array.length]luôn luôn truy cập một phần tử trong mảng của tôi thay vì cố gắng lập chỉ mục các vị trí phủ định.
Kris

2
(x % y + y) % y hoặc bắt đầu ở Java 8,Math.floorMod(x, y)
Greg Charles

12

Mặc dù có thể thực hiện một modulo thích hợp bằng cách kiểm tra xem giá trị có âm hay không và sửa nó nếu đúng (theo cách mà nhiều người đã đề xuất), có một giải pháp nhỏ gọn hơn.

(a % b + b) % b

Điều này trước tiên sẽ thực hiện modulo, giới hạn giá trị trong phạm vi -b -> + b và sau đó thêm b để đảm bảo giá trị là dương, hãy để modulo tiếp theo giới hạn ở phạm vi 0 -> b.

Lưu ý: Nếu b âm tính, kết quả cũng sẽ âm


Điều này có thể tràn khi a và b đều là số lớn, vì vậy nó không phải là một giải pháp chính xác.
Sói Trixie

11

Mã chạy nhanh hơn nhiều mà không cần sử dụng modulo:

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

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

3
Điều này có vẻ sạch sẽ hơn nhiều so với câu trả lời được chấp nhận. Điều này không có gì để làm với tối ưu hóa sớm. Nó chỉ đơn giản là tốt hơn, - nếu nó hoạt động.
AlexWien

4
@LluisMartinez Đây là một trong những câu nói sai nhất trong điện toán. Câu trích dẫn đầy đủ là "Các lập trình viên lãng phí rất nhiều thời gian để suy nghĩ hoặc lo lắng về tốc độ của các phần không văn bản trong chương trình của họ và những nỗ lực này có hiệu quả thực sự có tác động tiêu cực mạnh khi gỡ lỗi và bảo trì. Chúng ta nên quên đi việc nhỏ tính hiệu quả, nói khoảng 97% thời gian: tối ưu hóa sớm là gốc rễ của mọi tội lỗi. Tuy nhiên, chúng ta không nên bỏ qua cơ hội của mình trong 3% quan trọng đó. " Điều này thực sự có nghĩa là một cái gì đó khá khác nhau.
Hầu tước Lorne

3
@EJP Có lẽ bạn đúng. Tôi đã thực hiện một thử nghiệm (vòng lặp với 1 triệu lần lặp) mất 4000 nano giây với modulo, 2500 nano giây với logic và.
Lluis Martinez

Tại sao điều này sẽ là một câu trả lời? Chắc chắn rằng nó thậm chí lẻ, nhưng không làm gì với toán tử mod / phần còn lại. Câu hỏi nói về toán tử mod, không phải làm thế nào để tìm lẻ.
Đánh dấu Walsh



4

Trong Java, nó là %toán tử: 15.17.3. Toán tử còn lại%

Lưu ý rằng cũng có floorModtrong java.lang.Mathlớp sẽ cho kết quả khác với %các đối số có dấu hiệu khác nhau:

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


1
Được nâng cấp, bởi vì floorMod là toán tử 'modulo' tốt hơn %vì nó cũng hoạt động đúng khi đối số cũng âm. Không có câu trả lời nào khác thực sự đúng vì chúng đi kèm với tuyên bố từ chối trách nhiệm rằng% không thực sự là modulo trừ khi các đối số là tích cực. Cụ thể, nếu bạn muốn ánh xạ mọi số nguyên sang một vị trí liên tiếp trong một mảng thì array[floorMod(i, array.length)hoạt động chính xác ngay cả khi chỉ mục iđi vào lãnh thổ âm. Không như vậy với %.
Kris

3

Ngoài ra, mod có thể được sử dụng như thế này:

int a = 7;
b = a % 2;

bsẽ bằng 1. Bởi vì 7 % 2 = 1.


có thể là một sai lầm khi sử dụng các toán tử ghép trong một ví dụ cho người mới bắt đầu và không có đầu ra.
Stu Thompson

3

Toán tử còn lại trong Java là %và toán tử modulo có thể được biểu diễn dưới dạng

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

Như những người khác đã chỉ ra, %toán tử (phần còn lại) không giống như toán tử mod/ hàm hoạt động mô đun toán học .

mod đấu với %

Các x mod nchức năng ánh xạ xđến ntrong phạm vi [0,n).
Trong khi các x % nnhà điều hành ánh xạ xđến ntrong phạm vi (-n,n).

Để có một phương pháp sử dụng hoạt động mô đun toán học và không quan tâm đến dấu hiệu phía trước xngười ta có thể sử dụng:

((x % n) + n) % n

Có lẽ hình ảnh này giúp hiểu rõ hơn về nó (tôi đã có một khoảng thời gian khó khăn trong đầu này)

nhập mô tả hình ảnh ở đây


1
Bản vẽ đẹp. Một sự phức tạp khác: điều này không tính đến mô đun 2 ^ 32 của intchính biến đó. Các floorModphương pháp không làm điều đó một cách chính xác (nhưng bạn có thể cần phải tính toán bổ sung nếu nlà tiêu cực).
Maarten Bodewes

1

Một cách khác là:

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

Nhưng cách dễ nhất vẫn là:

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

Giống như @Steve Kuo đã nói.


0

Trong Java, hoạt động mod có thể được thực hiện như sau:

Math.floorMod(a, b)

Lưu ý: Các mod hoạt động khác với phần còn lại hoạt động. Trong Java, hoạt động còn lại có thể được thực hiện như sau:

a % b

Cũng không chính xác ... javadoc Math.floorMod()có nó: 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).Vì vậy, nó không hoàn toàn giống như mô đun toán học. Nhưng , có một cách để có được kết quả tích cực, cũng trong Javadoc của cùng một phương pháp: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 Điều đó có thể đúng, nhưng nếu bạn biết rằng mô đun là dương thì floorModhoạt động sẽ hoạt động như mong đợi. Cũng có floorModcho longgiá trị và nếu không có sự BigIntegercho các giá trị lớn hơn.
Maarten Bodewes

-1

Toán tử modulo là% (dấu phần trăm). Để kiểm tra độ đồng đều hoặc thường làm modulo cho công suất 2, bạn cũng có thể sử dụng & (toán tử và toán tử) như isEven =! (A & 1).


-3

Một thay thế cho mã từ @Cody:

Sử dụng toán tử mô đun:

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

Tôi nghĩ rằng đây là mã tốt hơn so với viết if / other, bởi vì có ít sự trùng lặp & linh hoạt không sử dụng. Nó đòi hỏi một chút năng lực não bộ để kiểm tra, nhưng việc đặt tên tốt cho sự isEvenbù trừ.


2
Đó là toán tử còn lại, không phải toán tử mô đun.
Hầu tước Lorne

@EJP ok. Vậy thì toán tử mô đun là gì?
TheRealChx101
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.