ไวยากรณ์สำหรับ mod ใน java คืออะไร


คำตอบ:


357

แทนของผู้ประกอบการโมดูโลซึ่งมีความหมายแตกต่างกันเล็กน้อยสำหรับจำนวนเต็มไม่เป็นลบ, คุณสามารถใช้ที่เหลือ%ผู้ประกอบการ สำหรับตัวอย่างที่แน่นอนของคุณ:

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

สิ่งนี้สามารถทำให้เป็นหนึ่งซับได้ง่าย:

isEven = (a % 2) == 0;

80
ถ้า / else ไม่จำเป็นเพียงใช้ isEven = (a% 2) == 0,
Steve Kuo

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
นี่ไม่ใช่ตัวดำเนินการโมดูลัส - เป็นตัวดำเนินการส่วนที่เหลือ โปรดแก้ไขการโพสต์!
Kieren Johnstone

2
บูลีนแม้ = ((& & 1) == 0) ง่ายกว่ามาก.
mdev

111

นี่เป็นตัวแทนของรหัสเทียมของคุณในรหัส Java น้อยที่สุด;

boolean isEven = a % 2 == 0;

ตอนนี้ฉันจะแยกมันออกเป็นส่วนประกอบ ตัวดำเนินการโมดูลัสใน Java คืออักขระเปอร์เซ็นต์ (%) ดังนั้นการรับ int% int จะส่งคืน int อื่น ตัวดำเนินการ double equals (==) ถูกใช้เพื่อเปรียบเทียบค่าเช่นคู่ของ int และส่งคืนบูลีน นี่จะถูกกำหนดให้กับตัวแปรบูลีน 'isEven' ขึ้นอยู่กับความสำคัญของผู้ประกอบการโมดูลัสจะถูกประเมินก่อนการเปรียบเทียบ


12
น้อยที่สุดจะไม่มีวงเล็บ;)
pstanton

3
มันเป็นตัวดำเนินการส่วนที่เหลือไม่ใช่ตัวดำเนินการโมดูลัส
มาร์ควิสแห่ง Lorne

@ user207421 ชื่อจริง ๆ แล้วมันคือตัวดำเนินการที่เหลือแต่ไม่เท่ากับ: " โมดูลัส - 4 (การคำนวณ, การเขียนโปรแกรม)ตัวดำเนินการวางอยู่ระหว่างตัวเลขสองตัวเพื่อให้ได้ส่วนที่เหลือของตัวเลขเหล่านั้น"?
GeroldBroser คืนสถานะโมนิก้า

93

เนื่องจากคนอื่นให้คำตอบแล้วฉันจะเพิ่มบริบทเพิ่มเติมเล็กน้อย % ตัวดำเนินการ "โมดูลัส" กำลังทำการดำเนินการส่วนที่เหลือ ความแตกต่างระหว่าง mod และ rem นั้นบอบบาง แต่สำคัญ

(-1 mod 2) โดยปกติแล้วจะให้ 1 โดยเฉพาะอย่างยิ่งที่ได้รับสองจำนวนเต็ม X และ Y การดำเนินการ (X mod Y) มีแนวโน้มที่จะกลับค่าในช่วง [0, Y) กล่าวว่าแตกต่างกันโมดูลัสของ X และ Y มักจะมากกว่าหรือเท่ากับศูนย์และน้อยกว่า Y

ทำการดำเนินการเดียวกันกับ "%" หรือตัวดำเนินการ rem จะรักษาเครื่องหมายของค่า X ถ้า X เป็นลบคุณจะได้ผลลัพธ์ในช่วง (-Y, 0] ถ้า X เป็นบวกคุณจะได้ผลลัพธ์ในช่วง [0, Y)

บ่อยครั้งที่ความแตกต่างที่ลึกซึ้งนี้ไม่สำคัญ กลับไปที่คำถามรหัสของคุณแม้ว่าจะมีวิธีการแก้ปัญหาหลายวิธีสำหรับ "สมดุล"

วิธีแรกเป็นวิธีที่ดีสำหรับผู้เริ่มต้นเพราะโดยเฉพาะอย่างยิ่ง verbose

// 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 ของ) จะเหลือเป็นแบบฝึกหัดให้ผู้อ่าน ;)

หวังว่าจะช่วย


ขอบคุณ Rob ความสับสนนี้ทำให้เกิดความยากลำบากอย่างมากในการอธิบายให้โปรแกรมเมอร์เขียนว่าจะใช้อัลกอริธึมที่มีคุณสมบัติทางคณิตศาสตร์จากการคำนวณแบบแยกส่วนได้อย่างไร ส่วนที่เหลือไม่ได้เป็นโมดูลัส แต่อย่างใดอย่างหนึ่งสามารถได้รับโมดูลัสจากส่วนที่เหลือ
จิม

1
@TickledPink ยกเว้นว่านี่จะไม่ได้รวบรวมใน Java
Eugene Beresovsky

33

ในการทำให้การดำเนินการ% (REM) ของ Java ทำงานเช่น 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)
Greg Charles

12

ในขณะที่เป็นไปได้ที่จะทำแบบโมดูโลที่เหมาะสมโดยตรวจสอบว่าค่าเป็นลบและแก้ไขถ้าเป็น (วิธีที่หลายคนแนะนำ) มีวิธีแก้ไขปัญหาที่กะทัดรัดกว่า

(a % b + b) % b

สิ่งนี้จะทำการโมดูโลก่อนการ จำกัด ค่าในช่วง -b -> + b แล้วเพิ่ม b เพื่อให้แน่ใจว่าค่าเป็นบวกปล่อยโมดูโลต่อไป จำกัด ให้อยู่ในช่วง 0 -> b

หมายเหตุ: ถ้า b เป็นลบผลลัพธ์จะเป็นลบเช่นกัน


สิ่งนี้สามารถล้นเมื่อ a และ b เป็นจำนวนมากดังนั้นจึงไม่ใช่วิธีที่ถูกต้อง
ทริกซี่หมาป่า

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% " ซึ่งจริงๆแล้วหมายถึงบางสิ่งที่แตกต่างออกไป
มาร์ควิสแห่ง Lorne

3
@EJP คุณอาจพูดถูก ฉันทำการทดสอบ (วนซ้ำ 1 ล้านรอบ) เอา 4000 นาโนวินาทีด้วยโมดูโล, 2500 นาโนวินาทีด้วยตรรกะและ
Lluis Martinez

ทำไมนี่จึงเป็นคำตอบ แน่ใจว่ามันจะแปลกแม้ แต่ไม่ได้ทำอะไรกับผู้ประกอบการ mod / ส่วนที่เหลือ คำถามพูดคุยเกี่ยวกับตัวดำเนินการ mod ไม่ใช่วิธีการหาคี่
Mark Walsh



4

ใน Java เป็น%ผู้ดำเนินการ: 15.17.3 ผู้ประกอบการที่เหลืออยู่%

โปรดทราบว่ายังมีfloorModในjava.lang.Mathชั้นเรียนซึ่งจะให้ผลลัพธ์ที่แตกต่างจาก%การขัดแย้งกับสัญญาณที่แตกต่างกัน:

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


1
เพิ่มขึ้นเนื่องจาก floorMod เป็นตัวดำเนินการ 'modulo' ที่ดีกว่า%เนื่องจากมันทำงานได้อย่างถูกต้องเมื่ออาร์กิวเมนต์เป็นค่าลบเช่นกัน ไม่มีคำตอบอื่นใดที่ถูกต้องจริง ๆ เนื่องจากพวกเขามาพร้อมกับข้อจำกัดความรับผิดชอบที่% นั้นไม่โมดูโล่จริง ๆ เว้นแต่ว่าข้อโต้แย้งนั้นจะเป็นบวก โดยเฉพาะอย่างยิ่งถ้าคุณต้องการแมปจำนวนเต็มทุกตำแหน่งไปยังตำแหน่งต่อเนื่องในอาร์เรย์แล้วarray[floorMod(i, array.length)ทำงานอย่างถูกต้องแม้ว่าดัชนีiจะเข้าสู่พื้นที่เชิงลบ %ไม่ให้มี
กริช

3

นอกจากนี้ mod ยังสามารถใช้ดังนี้:

int a = 7;
b = a % 2;

bจะเท่ากับ 1 7 % 2 = 1เนื่องจาก


อาจเป็นความผิดพลาดในการใช้ตัวดำเนินการผสมในตัวอย่างสำหรับผู้เริ่มต้นและไม่มีเอาต์พุต
Stu Thompson

3

ตัวดำเนินการส่วนที่เหลือใน Java คือ%และตัวดำเนินการ modulo สามารถแสดงเป็น

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 VS %

x mod nฟังก์ชั่นแผนที่xจะอยู่ในช่วงของn ในขณะที่ผู้ประกอบการมีแผนที่จะอยู่ในช่วงของ[0,n)
x % nxn(-n,n)

เพื่อให้มีวิธีการใช้การดำเนินการโมดูลัสทางคณิตศาสตร์และไม่สนใจเกี่ยวกับการลงชื่อในหน้าxหนึ่งสามารถใช้:

((x % n) + n) % n

บางทีรูปนี้อาจช่วยให้เข้าใจได้ดีขึ้น (ฉันมีปัญหาในการพันหัวก่อน)

ป้อนคำอธิบายรูปภาพที่นี่


1
การวาดภาพที่ดี ความซับซ้อนอื่น ๆ : สิ่งนี้ไม่คำนึงถึงความเป็นโมดุลของintตัวแปร2 ^ 32 floorModวิธีการไม่ทำอย่างนั้นอย่างถูกต้อง ( แต่คุณอาจต้องคำนวณเพิ่มเติมหากnเป็นลบ)
Maarten Bodewes

1

อีกวิธีคือ:

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

แต่วิธีที่ง่ายที่สุดยังคงเป็น:

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

กด Like @Steve Kuo


0

ในJavaการดำเนินการmodสามารถทำได้ดังนี้:

Math.floorMod(a, b)

หมายเหตุ: การดำเนินการmodจะแตกต่างจากการดำเนินการส่วนที่เหลือ ใน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

@ WesternGun นั่นอาจเป็นจริง แต่ถ้าคุณรู้ว่าโมดูลัสเป็นบวกการfloorModดำเนินการก็จะเป็นไปตามที่คาดไว้ นอกจากนี้ยังมีค่าfloorModสำหรับlongค่ามิฉะนั้นจะBigIntegerมีค่าที่ใหญ่กว่า
Maarten Bodewes

-1

ตัวดำเนินการ modulo คือ% (เครื่องหมายเปอร์เซ็นต์) เพื่อทดสอบความสมดุลหรือโดยทั่วไปทำโมดูโลสำหรับกำลัง 2 คุณยังสามารถใช้ & (และและตัวดำเนินการ) เช่น isEven =! (a & 1)


-3

ทางเลือกสำหรับรหัสจาก @Cody:

การใช้ตัวดำเนินการโมดูลัส:

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

ฉันคิดว่านี่เป็นโค้ดที่ดีกว่าการเขียนถ้า / อย่างอื่นเนื่องจากมีการทำซ้ำน้อยลงและมีความยืดหยุ่นที่ไม่ได้ใช้ มันต้องการพลังสมองมากขึ้นในการตรวจสอบ แต่การตั้งชื่อที่ดีของการisEvenชดเชย


2
มันเป็นตัวดำเนินการส่วนที่เหลือไม่ใช่ตัวดำเนินการโมดูลัส
มาร์ควิสแห่ง Lorne

@EJP ตกลง แล้วผู้ประกอบการโมดูลัสคืออะไร?
TheRealChx101
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.