JavaRush /จาวาบล็อก /Random-TH /ตัวดำเนินการเชิงตรรกะใน Java

ตัวดำเนินการเชิงตรรกะใน Java

เผยแพร่ในกลุ่ม
การดำเนินการเชิงตรรกะใน Java  การดำเนินการ Bitwise ใน Java - 1

การดำเนินการเชิงตรรกะใน Java

การดำเนินการทางลอจิคัลดำเนินการโดยใช้ตัวดำเนินการบูลีน ขออภัยที่ซ้ำซาก แต่นี่คือสิ่งที่เป็นอยู่จริงๆ การดำเนินการทางตรรกะขั้นพื้นฐาน (ในการเขียนโปรแกรมและคณิตศาสตร์) สามารถนำไปใช้กับอาร์กิวเมนต์เชิงตรรกะ (ตัวถูกดำเนินการ) และยังสามารถใช้เพื่อสร้างนิพจน์ที่ซับซ้อนมากขึ้นได้ คล้ายกับการดำเนินการทางคณิตศาสตร์กับตัวเลข ตัวอย่างเช่นนิพจน์:

(a | b) | (c < 100) & !(true) ^ (q == 5)
เป็นนิพจน์เชิงตรรกะที่ซับซ้อนซึ่งมีตัวถูกดำเนินการสี่ตัว: (a | b)โดยที่аและbเป็นตัวแปรประเภทboolean (c < 100) (true) (q == 5) ในทางกลับกัน นิพจน์เชิงตรรกะอย่างง่าย(a | b)ยังประกอบด้วยอาร์กิวเมนต์ตัวถูกดำเนินการสองตัวด้วย ตัวถูกดำเนินการเชิงตรรกะคือนิพจน์ที่สามารถพูดได้ว่าเป็นจริงหรือเท็จ จริงหรือเท็จ ในภาษาจาวา ตัวถูกดำเนินการบูลีนคือนิพจน์ประเภทbooleanหรือบูลีน ตัวอย่างเช่น:
  • (2 < 1)— ตัวถูกดำเนินการเชิงตรรกะ ค่าของมันคือเท็จ
  • true- ตัวถูกดำเนินการเชิงตรรกะที่มีค่าเป็นจริง อย่างเห็นได้ชัด
  • boolean a- สามารถเป็นตัวถูกดำเนินการเชิงตรรกะได้ เช่นBoolean a
  • int a = 2- ไม่ใช่ตัวถูกดำเนินการเชิงตรรกะแต่เป็นเพียงตัวแปรประเภทint
  • String a = "true"ไม่ใช่ตัวถูกดำเนินการเชิงตรรกะด้วย นี่คือสตริงที่มีค่าข้อความ"true"เป็น
การดำเนินการทางลอจิคัลต่อไปนี้มีอยู่ใน Java:
  • การปฏิเสธเชิงตรรกะหรือที่เรียกNOTว่าการผกผัน ใน Java จะถูกระบุด้วย!สัญลักษณ์ “ ” หน้าตัวถูกดำเนินการ ใช้กับตัวถูกดำเนินการหนึ่งตัว
  • ตรรกะ และมันยังเป็นANDส่วนร่วม ด้วย ระบุด้วย&สัญลักษณ์ “ ” ระหว่างตัวถูกดำเนินการทั้งสองตัวที่ใช้
  • เชิงตรรกะหรือใน Javaก็เป็น - เช่นกันORก็เป็นการแยกส่วนเช่นกัน ในภาษา Java จะมีการระบุด้วยสัญลักษณ์ “ |” ระหว่างตัวถูกดำเนินการสองตัว
  • พิเศษ หรือ , XORการแยกอย่างเข้มงวด ในภาษา Java จะมีการระบุด้วยสัญลักษณ์ “ ^” ระหว่างตัวถูกดำเนินการสองตัว
  • ในJava ตัวดำเนินการเชิงตรรกะจะรวมเงื่อนไข หรือที่แสดงเป็น เช่น||เดียวกับเงื่อนไข และ -&&
หมายเหตุ:ในตรรกะทางคณิตศาสตร์พวกเขาพิจารณาความสัมพันธ์ที่เท่าเทียมกันหรืออีกนัยหนึ่งคือความเท่าเทียมกัน อย่างไรก็ตาม ใน Java ตัวดำเนินการความเท่าเทียมกัน==ไม่ถือเป็นตัวดำเนินการเชิงตรรกะ ความสนใจ! ใน Java ตัวดำเนินการเชิงตรรกะ&และ|ไป^ใช้กับจำนวนเต็ม ในกรณีนี้ พวกมันทำงานแตกต่างออกไปเล็กน้อย และเรียกว่า ตัวดำเนินการเชิงตรรกะ ระดับบิต (หรือระดับบิต) เกี่ยวกับพวกเขา - ในตอนท้ายของบทความ ลองดูตารางที่มีคำอธิบายโดยย่อของตัวดำเนินการเชิงตรรกะ Java แต่ละตัว และด้านล่างเราจะอธิบายรายละเอียดเพิ่มเติมพร้อมให้ตัวอย่างโค้ด
ตัวดำเนินการจาวา ชื่อ พิมพ์ คำอธิบายสั้น ตัวอย่าง
! ตรรกะ “ไม่” (ปฏิเสธ) อูนารี !xหมายถึง "ไม่ใช่ x" คืนค่าเป็นจริงหากตัวถูกดำเนินการเป็นเท็จ คืนค่าเท็จหากตัวถูกดำเนินการเป็นจริง boolean x = true;
แล้ว
// !x == false
& ตรรกะ และ ( AND, การคูณ) ไบนารี่ คืนค่าเป็นจริงหากตัวถูกดำเนินการทั้งสองเป็นจริง a = true;
b = false;
แล้ว
a & b == false
| ตรรกะหรือ ( OR, นอกจากนี้) ไบนารี่ คืนค่าเป็นจริงหากตัวถูกดำเนินการอย่างน้อยหนึ่งตัวเป็นจริง a = true;
b = false;
แล้ว
a | b == true
^ ตรรกะพิเศษหรือ ( XOR) ไบนารี่ คืนค่าเป็นจริงหากมีตัวถูกดำเนินการเพียงตัวเดียวเท่านั้นที่เป็นจริง ส่งคืนค่าเท็จหากตัวถูกดำเนินการทั้งสองเป็นจริงหรือเท็จ โดยพื้นฐานแล้ว มันจะคืนค่าเป็นจริงหากตัวถูกดำเนินการต่างกัน a = true;
b = false;
แล้ว
a ^ b == true
&& AND แบบมีเงื่อนไข (แบบตรรกะแบบสั้น AND) ไบนารี่ เช่นเดียวกับ&แต่หากตัวถูกดำเนินการทางด้านซ้ายของ&เป็นfalseตัวดำเนินการนี้จะส่งคืนค่าfalseโดยไม่ตรวจสอบตัวถูกดำเนินการตัวที่สอง
|| เงื่อนไขหรือ (ตรรกะสั้นหรือ) ไบนารี่ เช่นเดียวกับ|แต่หากตัวดำเนินการทางด้านซ้ายเป็นจริงตัวดำเนินการจะคืนค่าจริงโดยไม่ตรวจสอบตัวถูกดำเนินการตัวที่สอง

การดำเนินการเชิงตรรกะในหลักสูตร JavaRush

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

การดำเนินการเชิงตรรกะใน Java  การดำเนินการ Bitwise ใน Java - 2

ตัวดำเนินการปฏิเสธเชิงตรรกะ !

ตัวดำเนินการนี้เป็นเอกพจน์ ซึ่งหมายความว่าใช้กับนิพจน์บูลีนหรือตัวถูกดำเนินการเดียว มันง่ายมากที่จะเข้าใจ เช่นเดียวกับการปฏิเสธอื่นๆ: ตัวดำเนินการเพียงแค่เปลี่ยนความหมายของนิพจน์ไปในทางตรงกันข้าม ตารางความจริงหรือผลลัพธ์ของการดำเนินการปฏิเสธ:
มูลค่าของ !ก
เท็จ จริง
จริง เท็จ
ตัวอย่าง. การดำเนินการปฏิเสธเชิงตรรกะ
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       System.out.println(!a); // here our boolean expression reverses its value
       System.out.println(!false); // non-false expression, as you might guess, will be equal to... what?
       System.out.println(!(2 < 5)); // expression (2 < 5) is true, so its negation is false

   }
}
ผลลัพธ์ของโปรแกรมจะเป็นดังนี้:

false
true
false

ตรรกะ AND - & รวมถึงเงื่อนไข AND - &&

ตรรกะ AND หรือการรวมกันใช้กับสองนิพจน์ และผลลัพธ์จะเป็นจริง ก็ต่อ เมื่อตัวถูกดำเนินการทั้งสองเป็นจริงเท่านั้น นั่นคือ ถ้าหนึ่งในaหรือ ถูกดำเนินการ bเป็นเท็จนิพจน์a & bจะเป็นเท็จโดยไม่คำนึงถึงค่าของตัวดำเนินการที่สอง หากคุณจินตนาการว่าจริงคือเลข 1 และเท็จคือ 0 ตัวดำเนินการ&จะทำงานเหมือนกับการคูณปกติทุกประการ ดังนั้น ตรรกะ AND จึงมักเรียกว่า "การคูณเชิงตรรกะ" และความจริงข้อนี้ช่วยให้จดจำการทำงานของตัวดำเนินการได้อย่างรวดเร็ว&และไม่สับสนกับตรรกะหรือตัวดำเนินการ|. ตารางความจริง และ เป็นผลจากการทำงานของผู้ปฏิบัติงานด้วย&
เอแอนด์บี
จริง จริง จริง
จริง เท็จ เท็จ
เท็จ จริง เท็จ
เท็จ เท็จ เท็จ
ตรรกะ AND ยังเป็นคำร่วมด้วย ตัวอย่าง:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(a & b); // if we multiply true by false, we will definitely get false
       System.out.println(a & c); // true to true will be true
       System.out.println(false & (2 > 5));
 System.out.println((2 < 5) & false);
 // regardless of the truthfulness of the expression in brackets, in which case we have to be content with false
   }
}
ผลลัพธ์ของโปรแกรม:

false
true
false
false
ตัวดำเนินการ&&บางครั้งเรียกว่า "short AND" มันให้ผลลัพธ์เดียวกันเมื่อทำงานกับตัวถูกดำเนินการเชิงตรรกะเหมือนกับตัวดำเนิน&การ อย่างไรก็ตาม งานของเขามีความแตกต่างกัน ดังนั้นคุณสังเกตแล้วว่าหากa & bตัวถูกดำเนินการในนิพจน์ ( ) aเป็นเท็จก็ไม่สมเหตุสมผลที่จะตรวจสอบค่าของตัวถูกดำเนินการb: ผลลัพธ์ของการดำเนินการจะเป็นเท็จ อย่าง แน่นอน ดังนั้นหากเราไม่ต้องการค่าของตัวถูกดำเนินการตัวที่สองโดยพื้นฐาน การใช้ค่าดังกล่าว&&จะเป็นการลดจำนวนการคำนวณในโปรแกรม หากเราแทนที่ตัวดำเนินการทั้งหมดในตัวอย่าง&ด้วย&&ผลลัพธ์จะเหมือนกันทุกประการ แต่ตัวโปรแกรมเองจะทำงานเร็วขึ้นเล็กน้อย (แม้ว่าเราจะไม่สังเกตเห็นสิ่งนี้ เนื่องจากเรากำลังพูดถึง mili-micro... กล่าวโดยย่อ หน่วยเวลาอันสั้นมาก)

Logical OR คือตัวดำเนินการ | เช่นเดียวกับเงื่อนไข OR คือตัวดำเนินการ ||

|ตัวดำเนินการ OR ใน Java จะแสดงด้วยสัญลักษณ์ ตรรกะ OR หรือการแยกส่วนใช้กับสองนิพจน์ และผลลัพธ์จะเป็นเท็จถ้าหากตัวถูกดำเนินการทั้งสองเป็นเท็จ ที่นี่เราสังเกตภาพเดียวกันกับในกรณีของตัวดำเนินการในระดับหนึ่ง&แต่ตรงกันข้ามทุกประการ นั่นคือ ถ้ามีตัวถูกดำเนินการอย่างน้อยหนึ่งตัวเป็นจริงนิพจน์a | bจะรับประกันว่าจะเป็นจริงโดยไม่คำนึงถึงค่าของตัวดำเนินการตัวที่สอง ถ้า&มันทำงานเหมือนกับการคูณเชิงตรรกะ OR ก็คือการบวกเชิงตรรกะ หากคุณจินตนาการว่าเป็นจริงเป็น 1 และเท็จเป็น 0 เพียงจำไว้ว่าการบวกเชิงตรรกะทำงานแตกต่างจากการบวกปกติ 1 + 1 ในกรณีนี้ไม่เท่ากับ 2 แต่เป็น 1 (ตัวเลข 2 ไม่มีอยู่ในระบบนี้) บางครั้ง การแยกกันอาจเข้าใจว่ามีค่าสูงสุดคือ 0 และ 1 และในกรณีนี้ หากอย่างน้อยหนึ่งตัวถูกดำเนินการเท่ากับ 1 ( true ) เราจะได้ค่าtrue ทุก ประการ หรือตารางความจริงหรือที่เรียกว่าผลลัพธ์ของตัวดำเนินการ|:
ก | ข
จริง จริง จริง
จริง เท็จ จริง
เท็จ จริง จริง
เท็จ เท็จ เท็จ
Logical OR หรือที่รู้จักกันในชื่อ Disjunction ตัวอย่าง:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a | b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
       System.out.println(a | c);
       System.out.println((2 < 5) | false); // expression (2 < 5) is true, which means that for any second operand we get a true result
       System.out.println((2 > 5) | true);

   }
}
ผลลัพธ์:

false
true
true
true
หากเราใช้ตัวดำเนินการแบบมีเงื่อนไขหรือ - ||แทนที่จะเป็น|เราจะได้ผลลัพธ์เดียวกันทุกประการ แต่ในกรณีของแบบมีเงื่อนไข AND &&มันจะทำหน้าที่เชิงเศรษฐกิจ: ถ้าเรา "วิ่งเข้าไป" ตัวถูกดำเนินการตัวแรกเท่ากับtrueค่าของ ตัวถูกดำเนินการที่สองไม่ได้ถูกตรวจสอบ แต่ผลลัพธ์จะเป็นจริง ทันที

XOR Java - โลจิคัลพิเศษหรือ - โอเปอเรเตอร์ ^

XOR, การบวกแบบโมดูโล 2, ตรรกะ XOR, การลบเชิงตรรกะ, การแยกส่วนอย่างเข้มงวด, ส่วนเสริมระดับบิต... ตัวดำเนินการ^มีหลายชื่อในพีชคณิตแบบบูล ผลลัพธ์ของการใช้ตัวดำเนินการนี้กับตัวถูกดำเนินการสองตัวจะเป็นจริงหากตัวถูกดำเนินการต่างกันและเป็นเท็จหากตัวถูกดำเนินการเหมือนกัน ดังนั้นจึงสะดวกที่จะเปรียบเทียบกับการลบศูนย์ ( เท็จ ) และอัน ( จริง ) ตารางความจริงXORหรือที่เรียกว่าผลลัพธ์ของตัวดำเนินการ^:
บูลีน เอ บูลีนข เอ^บี
จริง จริง เท็จ
จริง เท็จ จริง
เท็จ จริง จริง
เท็จ เท็จ เท็จ
ตัวอย่าง:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a ^ b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
       System.out.println(a ^ c);
       System.out.println((2 < 5) ^ false);
       System.out.println((2 > 5) ^ true);
   }
}
ผลลัพธ์:

false
false
true
true

ลำดับความสำคัญของการดำเนินการเชิงตรรกะ

เช่นเดียวกับในวิชาคณิตศาสตร์ ในตัวดำเนินการโปรแกรมจะมีลำดับการดำเนินการเฉพาะเมื่อปรากฏในนิพจน์เดียวกัน ตัวดำเนินการเอกนารีมีข้อได้เปรียบเหนือตัวดำเนินการไบนารี และการคูณ (แม้แต่ตรรกะ) มากกว่าการบวก เราได้จัดอันดับตัวดำเนินการเชิงตรรกะให้สูงกว่าในรายการ โดยจะมีลำดับความสำคัญสูงกว่า:
  1. !
  2. &
  3. ^
  4. |
  5. &&
  6. ||
ลองดูตัวอย่าง คำสันธานและคำสันธาน ( &และ|) มีลำดับความสำคัญต่างกัน:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println(a | b & c);
}
หากเราดำเนินการต่อจากซ้ายไปขวา กล่าวคือ ใช้โอเปอเรเตอร์ก่อน|จากนั้น - เรา&จะได้ค่าfalse แต่ในความเป็นจริง หากคุณรันโปรแกรมนี้ คุณจะมั่นใจได้ว่าผลลัพธ์จะเป็นtrueเนื่องจากตัวดำเนินการ AND แบบลอจิคัล&จะมีลำดับความสำคัญสูงกว่าตัวดำเนินการแบบลอจิคัล|OR เพื่อหลีกเลี่ยงความสับสน คุณต้องจำไว้ว่าสิ่งที่&มีลักษณะเหมือนการคูณ และ|สิ่งที่มีลักษณะเหมือนการบวก คุณสามารถเปลี่ยนลำดับความสำคัญได้ เพียงใช้วงเล็บเหมือนในคณิตศาสตร์ของโรงเรียน มาเปลี่ยนโค้ดตัวอย่างของเรากันสักหน่อย:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println((a|b)&c);
}
ว่าไง? อันดับแรก เราใช้การบวกเชิงตรรกะในวงเล็บ แล้วจึงคูณ ผลลัพธ์จะเป็น เท็จ

นิพจน์เชิงตรรกะที่ซับซ้อน

แน่นอนว่าเราสามารถรวมนิพจน์บูลีนและตัวดำเนินการเข้าด้วยกันได้ จำสำนวนจากจุดเริ่มต้นของบทความ:
(a | b) | (c < 100) & !(true) ^ (q == 5)
ตอนนี้ดูไม่น่ากลัวเท่าไหร่ มาเขียนโปรแกรมที่แสดงค่าโดยกำหนดค่าของa, bและсไว้ ก่อน qหน้า นี้ ตัวอย่างการคำนวณค่าของนิพจน์บูลีนที่ซับซ้อน
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       int c = 25;
       int q = 2;
       System.out.println((a|b) | (c < 100) & !(true)^(q == 5));
   }
}
บันทึก:ตัวแปรqของเรา เป็นประเภท intแต่q == 5นี่คือนิพจน์บูลีน และมีค่าเท่ากับfalseเนื่องจากด้านบนเราเริ่มต้นด้วยqหมายเลข 2 เช่นเดียวกับcตัวแปร จำนวนนี้เท่ากับ 25 แต่ (c < 100) เป็นนิพจน์บูลีนเท่ากับtrue ผลลัพธ์ของโปรแกรมนี้:

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

ตัวดำเนินการระดับบิต (ระดับบิต)

ในตอนต้นของบทความ เราได้กล่าวถึงตัวดำเนินการ &และสามารถนำมาใช้สัมพันธ์กับประเภทจำนวนเต็ม Java ได้ ในกรณีนี้คือตัวดำเนินการระดับบิต เรียกอีกอย่างว่า bitwise เนื่องจากหนึ่งหลักคือหนึ่งบิต และการดำเนินการเหล่านี้ทำงานเฉพาะกับบิต แน่นอนว่าพวกมันทำงานค่อนข้างแตกต่างไปจากตัวดำเนินการเชิงตรรกะ และเพื่อที่จะเข้าใจว่าอย่างไร คุณจำเป็นต้องรู้ว่าระบบเลขฐานสองคืออะไร หากคุณไม่รู้อะไรเกี่ยวกับเรื่องนี้หรือลืมไปโดยสิ้นเชิง เราขอแนะนำให้คุณอ่านบทความJava: bits and bytes ก่อน และเตือนทุกคนว่าในระบบเลขฐานสองมีเพียงสองหลัก - 0 และ 1 และข้อมูลทั้งหมด ในคอมพิวเตอร์จะแสดงอย่างแม่นยำโดยใช้ศูนย์และค่าที่มีเงื่อนไข ตัวเลขใด ๆ ที่เราคุ้นเคย (ทศนิยมสำหรับพวกมันมี 10 หลักที่แตกต่างกันตั้งแต่ 0 ถึง 9 ซึ่งเราเขียนตัวเลขใดก็ได้) สามารถแสดงได้ในระบบเลขฐานสอง คุณสามารถแปลงเลขฐานสิบให้เป็นเลขฐานสองได้โดยใช้การหารตามลำดับให้เป็นคอลัมน์โดยใช้ฐานระบบตัวเลข (2) เศษที่เหลือของการหารในแต่ละขั้นตอนซึ่งเขียนในลำดับย้อนกลับจะทำให้เราได้เลขฐานสองที่ต้องการ ตัวอย่างเช่น การแปลงเลขทศนิยม 103 เป็นการแทนเลขฐานสอง: |^การดำเนินการเชิงตรรกะใน Java  การดำเนินการ Bitwise ใน Java - 3

ระบบเลขฐานสองในหลักสูตร JavaRush

ในหลักสูตร JavaRush พวกเขาพูดคุยเกี่ยวกับระบบเลขฐานสองในขณะที่ศึกษาภารกิจ MultiThreading (ระดับ 10 การบรรยายที่ 1) หลังจากการบรรยายจะมีงานหลายอย่างสำหรับการรวม อย่างไรก็ตาม หัวข้อนี้ไม่ใช่เรื่องยากเลย และแม้ว่าคุณจะไม่ได้ไปได้ไกลขนาดนั้นในหลักสูตรนี้ คุณก็น่าจะเข้าใจได้

นอกเหนือจากและ&Java ยังใช้ตัวดำเนินการระดับบิต: |^
  • ~ ตัวดำเนินการปฏิเสธระดับบิต
  • >>เลื่อนไปทางขวา
  • >>>กะขวาระดับบิตที่ไม่ได้ลงนาม
  • <<เลื่อนไปทางซ้ายในระดับบิต
สำหรับผู้เริ่มต้น ตัวดำเนินการระดับบิตดูเหมือนสับสนและหลอกลวงมาก พวกเขามักไม่เข้าใจสิ่งที่พวกเขาต้องการยกเว้นเพื่อแก้ไขปัญหาทางการศึกษา ที่จริงแล้ว อย่างน้อยที่สุดก็สามารถนำมาใช้เพื่อจัดระเบียบการหารและการคูณที่มีประสิทธิภาพ และผู้เชี่ยวชาญก็ใช้สิ่งเหล่านี้ในการเข้ารหัส/ถอดรหัส การเข้ารหัส และสร้างตัวเลขสุ่ม

ตัวดำเนินการ Bitwise &, | และ ^

ลองดูตัวอย่างวิธีการทำงานของตัวดำเนินการเหล่านี้ สมมติว่าเรามีจำนวนเต็มสองตัว:
int a = 25;
int b = 112; 
เราจำเป็นต้องใช้การดำเนินการสามประการกับพวกเขาและ&แสดงผลลัพธ์บนหน้าจอ นี่คือรหัสโปรแกรม: |^
public class Solution {
   public static void main(String[] args) {

       int a = 25;
       int b = 112;

       int res1 = a & b;
       int res2 = a | b;
       int res3 = a ^ b;

       System.out.println("a & b = " + res1);
       System.out.println("a | b = " + res2);
       System.out.println("a ^ b = " + res3);

   }
}
ผลลัพธ์ของโปรแกรมมีดังนี้:

a & b = 16
a | b = 121
a ^ b = 105
หากคุณไม่เข้าใจสิ่งที่เกิดขึ้น ผลลัพธ์จะดูลึกลับมาก ในความเป็นจริงทุกอย่างง่ายกว่าที่คิด ตัวดำเนินการระดับบิต “ดู” ตัวเลขตัวถูกดำเนินการในรูปแบบไบนารี่ จากนั้นจะใช้ตัวดำเนินการเชิงตรรกะ&หรือ|กับ^ตัวเลข (บิต) ที่สอดคล้องกันของตัวเลขทั้งสอง ดังนั้น สำหรับ&บิตสุดท้ายของการแทนเลขฐานสองของเลข 25 บวกกับบิตสุดท้ายของการแทนเลขฐานสองของเลข 112 บิตสุดท้ายกับบิตสุดท้ายกับเลขสุดท้าย และอื่นๆ: การดำเนินการเชิงตรรกะใน Java  การดำเนินการ Bitwise ใน Java - 4ตรรกะเดียวกันนี้สามารถตรวจสอบได้ใน กรณีของ|และ^. การดำเนินการเชิงตรรกะใน Java  การดำเนินการ Bitwise ใน Java - 5

บิตเลื่อนไปทางซ้ายหรือขวา

มีตัวดำเนินการกะบิตหลายตัวใน Java โอเปอเรเตอร์ที่ใช้บ่อยที่สุด<<คือ>>และ โดยจะเลื่อนการแสดงเลขฐานสองของตัวเลขไปทางซ้ายหรือขวา ตามลำดับ และในกรณีของการเลื่อนไปทางขวา ขณะเดียวกันก็รักษาเครื่องหมายไว้ (เราจะอธิบายว่าการรักษาเครื่องหมายหมายถึงอะไรด้านล่าง) มีตัวดำเนินการกะขวาอีกตัว>>>หนึ่ง มันทำสิ่งเดียวกันแต่>>ไม่บันทึกเครื่องหมาย ลองดูงานของพวกเขาโดยใช้ตัวอย่าง int a = 13 a << 1เลื่อนบิตทั้งหมดของการแสดงเลขฐานสองของตัวเลข a ไปทางซ้าย 1 บิต เพื่อให้ง่ายขึ้น ลองนึกภาพเลข 13 ในไบนารี่เป็น 0000 1101 อันที่จริงแล้ว ตัวเลขนี้มีลักษณะดังนี้: 00000000 00000000 00000000 00001101 เนื่องจาก Java intจัดสรรตัวเลข 4 ไบต์หรือ 32 บิต อย่างไรก็ตาม สิ่งนี้ไม่ได้มีบทบาทในตัวอย่างนี้ ดังนั้นในตัวอย่างนี้ เราจะถือว่าตัวเลขของเราเป็นหนึ่งไบต์ การดำเนินการเชิงตรรกะใน Java  การดำเนินการ Bitwise ใน Java - 6บิตที่ว่างทางด้านขวาเต็มไปด้วยเลขศูนย์ จากการดำเนินการนี้ เราได้ตัวเลข 26 a << 2โดยจะเลื่อนบิตทั้งหมดของการแสดงเลขฐานสองของตัวเลขaไปทางซ้าย 2 บิต และบิตสองบิตที่ว่างทางด้านขวาจะเต็มไปด้วยศูนย์ ผลออกมาจะได้เลข 52 a << 3ผลที่ได้จะเป็น 104... สังเกตลายมั้ย? การเลื่อนไปทางaซ้ายตามตำแหน่ง n จะทำงานเหมือนกับการคูณตัวเลขaด้วย 2 ยกกำลังของ n เช่นเดียวกับจำนวนลบ จะ-13 << 3ได้ผลลัพธ์ -104 a >> nเลื่อนการแสดงเลขฐานสองของตัวเลข n ตำแหน่งไปทางขวา ตัวอย่างเช่น13 >> 1 แปลงตัวเลข 1101 ให้เป็นตัวเลข 0110 นั่นคือ 6 และ13 >> 2ผลลัพธ์จะเป็น 3 โดยพื้นฐานแล้ว เราหารตัวเลขด้วย 2 ยกกำลังของ n โดยที่ n คือจำนวนกะ ไปทางขวา แต่มีข้อแม้ประการหนึ่ง: หากตัวเลขเป็นเลขคี่ ในระหว่างการดำเนินการนี้ ดูเหมือนว่าเราจะรีเซ็ตบิตสุดท้ายของตัวเลข แต่ในแง่ลบสถานการณ์จะแตกต่างออกไปบ้าง สมมติว่าลองตรวจสอบว่าโปรแกรมจะผลิตอะไรถ้าคุณขอให้มันดำเนิน-13 >> 1การ คุณจะเห็นเลข -7 ไม่ใช่ -6 อย่างที่คิด สิ่งนี้เกิดขึ้นเนื่องจากวิธีจัดเก็บตัวเลขติดลบในภาษา Java และภาษาการเขียนโปรแกรมอื่นๆ พวกมันจะถูกเก็บไว้ในสิ่งที่เรียกว่าโค้ดเสริม ในกรณีนี้ เครื่องหมายที่มีนัยสำคัญที่สุด (หลักทางด้านซ้าย) จะถูกมอบให้กับเครื่องหมาย ในกรณีที่เป็นจำนวนลบ หลักที่สำคัญที่สุดคือ 1

รหัสเพิ่มเติม

ลองพิจารณาจำนวนint a = 13ดู หากในโปรแกรมคุณพิมพ์การแทนไบนารี่ไปยังคอนโซลโดยใช้คำสั่งSystem.out.println(Integer.toBinaryString(a));เราจะได้ 1101 อันที่จริงนี่เป็นสัญลักษณ์ชวเลขเนื่องจากหมายเลขประเภทintใช้หน่วยความจำ 4 ไบต์ดังนั้นคอมพิวเตอร์จึง "มองเห็น" ได้มากขึ้น แบบนี้:

00000000 00000000 00000000 00001101
หลักที่สำคัญที่สุดคือศูนย์ ซึ่งหมายความว่าเรามีจำนวนบวก หากต้องการแปลงเป็นรหัสเพิ่มเติม:
  1. เราเขียนตัวเลข -13 ในสิ่งที่เรียกว่า "รหัสโดยตรง" เมื่อต้องการทำเช่นนี้ ให้เปลี่ยนหลักที่สำคัญที่สุดของตัวเลขเป็น 1
    ผลลัพธ์ของการดำเนินการ:

    
    10000000 0000000 0000000 00001101
  2. ต่อไป เราจะกลับบิตทั้งหมด (เราเปลี่ยน 0 เป็น 1 และ 1 เป็น 0) ยกเว้นบิตเครื่องหมาย อันที่จริงเราได้เปลี่ยนมันไปแล้ว
    ผลลัพธ์ของการกระทำ:

    
    11111111 11111111 11111111 11110010

    (ใช่ ขั้นตอน 1 และ 2 สามารถรวมกันได้ แต่ควรคิดแบบนั้นจะดีกว่า)

  3. เพิ่ม 1 ให้กับตัวเลขผลลัพธ์
    ผลลัพธ์ของการกระทำ:

    
    11111111 11111111 11111111 11110011
ผลลัพธ์ที่ได้คือเลขฐานสอง -13 ซึ่งเขียนด้วยโค้ดเสริมของ two และการเปลี่ยนบิต (และการดำเนินการอื่นๆ) จะถูกนำไปใช้โดยเฉพาะ เพียงแต่ว่าความแตกต่างในตรรกะของการดำเนินการนั้นไม่ได้สังเกตเห็นได้ชัดในการดำเนินการทั้งหมด สมมติว่าสำหรับการเลื่อนไปทางซ้ายเหมือนกัน ความแตกต่างนั้นมองไม่เห็น เราสามารถทำงานกับจำนวนลบได้ในลักษณะเดียวกับจำนวนบวก ตอนนี้ขอเลื่อนไปทาง-13 >> 1ขวา เนื่องจากโอเปอเรเตอร์ของเรา>>จะรักษาเครื่องหมายไว้ ในการดำเนินการนี้ บิตทั้งหมดที่ปล่อยทางด้านซ้ายจะไม่ได้เติมด้วยศูนย์ แต่เต็มไปด้วยบิต เลยเปลี่ยนเบอร์.

11111111 11111111 11111111 11110011
ไปทางขวาหนึ่งบิต ส่งผลให้มีลำดับบิตดังต่อไปนี้:

11111111 11111111 11111111 11111001
หากเราแปลงตัวเลขนี้เป็นโค้ดโดยตรง (นั่นคือ ลบ 1 ก่อน แล้วกลับบิตทั้งหมดยกเว้นบิตแรก) เราจะได้ตัวเลข:

10000000 00000000 00000000 00000111
หรือ -7 ตอนนี้เราได้เข้าใจตัวดำเนินการกะขวาเพื่อรักษาเครื่องหมายแล้ว ก็จะชัดเจนว่ามันแตกต่างจากตัวดำเนินการ>>>อย่างไร a >>> n— การดำเนินการนี้เป็นการเปลี่ยนแปลงที่ไม่ได้ลงนาม กล่าวคือ เป็นการเลื่อนการแสดงเลขฐานสองของตัวเลขaไปทางขวาด้วยจำนวน n บิต แต่จะเติมบิต n ที่ว่างทางด้านซ้าย ไม่ใช่ด้วยบิต เช่นเดียวกับตัวดำเนินการ>>แต่ด้วยศูนย์ มาทำการผ่าตัดกัน-13 >>> 1เถอะ เรามีตัวเลข-13เป็นส่วนเสริมของสองอยู่แล้ว:

11111111 11111111 11111111 11110011
เมื่อเลื่อนไปทางขวา 1 บิตแล้วเติมบิตว่างด้วยศูนย์ เราจะได้หมายเลขต่อไปนี้:

01111111 11111111 11111111 11111001
อะไรให้ตัวเลขในรูปแบบ2147483641ทศนิยม

ตัวดำเนินการปฏิเสธระดับบิต ~

ตัวดำเนินการเอกนารีนี้ทำงานง่ายมาก โดยจะกลับค่าแต่ละบิตของการแทนเลขฐานสองของจำนวนเต็ม มารับหมายเลขกัน-13:

11111111 11111111 11111111 11110011
การดำเนินการปฏิเสธระดับบิต~13จะกลับค่าของแต่ละบิต เป็นผลให้เราได้รับ:

00000000 00000000 00000000 00001100
หรือ12ในรูปแบบทศนิยม

ข้อสรุปโดยย่อ

  • ตัวดำเนินการเชิงตรรกะทั้งหมดนำไปใช้กับนิพจน์บูลี นกล่าวคือ ตัวดำเนินการที่สามารถระบุได้ว่าเป็นจริงหรือเท็จ
  • Если операторы &, | or ^ применяются к числам, речь идёт уже не о логических операциях, а о побитовых. То есть оба числа переводятся в двоичную систему и к этим числам побитово применяют операции логического сложения, умножения or вычитания.
  • В математической логике операторам & и | соответствуют конъюнкция и дизъюнкция.
  • Логическое И похоже на умножения 1 (true) и 0 (false).
  • Логическое ИЛИ напоминает поиск максимума среди 1 (true) и 0 (false).
  • Для побитового отрицания целого числа a используется операция ~a.
  • Для логического отрицания булевского выражения a используется операция !a.
  • Отрицательные числа хранятся и обрабатываются в дополнительном codeе.
  • Поразрядный сдвиг вправо может сохранять знак (>>), а может — не сохранять (>>>).
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION