- ตัวดำเนินการเชิงตรรกะใน Java
- ตัวดำเนินการปฏิเสธเชิงตรรกะ !
- ตรรกะ AND - & รวมถึงเงื่อนไข AND - &&
- Logical OR คือตัวดำเนินการ | เช่นเดียวกับเงื่อนไข OR คือตัวดำเนินการ ||
- XOR - ตรรกะพิเศษหรือ - ตัวดำเนินการ ^
- ลำดับความสำคัญของการดำเนินการเชิงตรรกะ
- นิพจน์เชิงตรรกะที่ซับซ้อน
- ตัวดำเนินการระดับบิต (ระดับบิต)
- ตัวดำเนินการ Bitwise &, | และ ^
- รหัสเพิ่มเติม
- ตัวดำเนินการปฏิเสธระดับบิต ~

การดำเนินการเชิงตรรกะใน 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 aint a = 2
- ไม่ใช่ตัวถูกดำเนินการเชิงตรรกะแต่เป็นเพียงตัวแปรประเภทint
String a = "true"
ไม่ใช่ตัวถูกดำเนินการเชิงตรรกะด้วย นี่คือสตริงที่มีค่าข้อความ"true"
เป็น
- การปฏิเสธเชิงตรรกะหรือที่เรียก
NOT
ว่าการผกผัน ใน Java จะถูกระบุด้วย!
สัญลักษณ์ “ ” หน้าตัวถูกดำเนินการ ใช้กับตัวถูกดำเนินการหนึ่งตัว - ตรรกะ และมันยังเป็น
AND
ส่วนร่วม ด้วย ระบุด้วย&
สัญลักษณ์ “ ” ระหว่างตัวถูกดำเนินการทั้งสองตัวที่ใช้ - เชิงตรรกะหรือใน Javaก็เป็น - เช่นกัน
OR
ก็เป็นการแยกส่วนเช่นกัน ในภาษา Java จะมีการระบุด้วยสัญลักษณ์ “|
” ระหว่างตัวถูกดำเนินการสองตัว - พิเศษ หรือ ,
XOR
การแยกอย่างเข้มงวด ในภาษา 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โดยไม่ตรวจสอบตัวถูกดำเนินการตัวที่สอง |
|
|| |
เงื่อนไขหรือ (ตรรกะสั้นหรือ) | ไบนารี่ | เช่นเดียวกับ| แต่หากตัวดำเนินการทางด้านซ้ายเป็นจริงตัวดำเนินการจะคืนค่าจริงโดยไม่ตรวจสอบตัวถูกดำเนินการตัวที่สอง |
ตัวดำเนินการปฏิเสธเชิงตรรกะ !
ตัวดำเนินการนี้เป็นเอกพจน์ ซึ่งหมายความว่าใช้กับนิพจน์บูลีนหรือตัวถูกดำเนินการเดียว มันง่ายมากที่จะเข้าใจ เช่นเดียวกับการปฏิเสธอื่นๆ: ตัวดำเนินการเพียงแค่เปลี่ยนความหมายของนิพจน์ไปในทางตรงกันข้าม ตารางความจริงหรือผลลัพธ์ของการดำเนินการปฏิเสธ:มูลค่าของ | !ก |
เท็จ | จริง |
จริง | เท็จ |
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 จึงมักเรียกว่า "การคูณเชิงตรรกะ" และความจริงข้อนี้ช่วยให้จดจำการทำงานของตัวดำเนินการได้อย่างรวดเร็ว&
และไม่สับสนกับตรรกะหรือตัวดำเนินการ|
. ตารางความจริง และ เป็นผลจากการทำงานของผู้ปฏิบัติงานด้วย&
ก | ข | เอแอนด์บี |
จริง | จริง | จริง |
จริง | เท็จ | เท็จ |
เท็จ | จริง | เท็จ |
เท็จ | เท็จ | เท็จ |
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 ทุก ประการ หรือตารางความจริงหรือที่เรียกว่าผลลัพธ์ของตัวดำเนินการ|
:
ก | ข | ก | ข |
จริง | จริง | จริง |
จริง | เท็จ | จริง |
เท็จ | จริง | จริง |
เท็จ | เท็จ | เท็จ |
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
ลำดับความสำคัญของการดำเนินการเชิงตรรกะ
เช่นเดียวกับในวิชาคณิตศาสตร์ ในตัวดำเนินการโปรแกรมจะมีลำดับการดำเนินการเฉพาะเมื่อปรากฏในนิพจน์เดียวกัน ตัวดำเนินการเอกนารีมีข้อได้เปรียบเหนือตัวดำเนินการไบนารี และการคูณ (แม้แต่ตรรกะ) มากกว่าการบวก เราได้จัดอันดับตัวดำเนินการเชิงตรรกะให้สูงกว่าในรายการ โดยจะมีลำดับความสำคัญสูงกว่า:!
&
^
|
&&
||
&
และ|
) มีลำดับความสำคัญต่างกัน:
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 เป็นการแทนเลขฐานสอง: |
^

ระบบเลขฐานสองในหลักสูตร 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 โอเปอเรเตอร์ที่ใช้บ่อยที่สุด<<
คือ>>
และ โดยจะเลื่อนการแสดงเลขฐานสองของตัวเลขไปทางซ้ายหรือขวา ตามลำดับ และในกรณีของการเลื่อนไปทางขวา ขณะเดียวกันก็รักษาเครื่องหมายไว้ (เราจะอธิบายว่าการรักษาเครื่องหมายหมายถึงอะไรด้านล่าง) มีตัวดำเนินการกะขวาอีกตัว>>>
หนึ่ง มันทำสิ่งเดียวกันแต่>>
ไม่บันทึกเครื่องหมาย ลองดูงานของพวกเขาโดยใช้ตัวอย่าง int a = 13
a << 1
เลื่อนบิตทั้งหมดของการแสดงเลขฐานสองของตัวเลข a ไปทางซ้าย 1 บิต เพื่อให้ง่ายขึ้น ลองนึกภาพเลข 13 ในไบนารี่เป็น 0000 1101 อันที่จริงแล้ว ตัวเลขนี้มีลักษณะดังนี้: 00000000 00000000 00000000 00001101 เนื่องจาก Java int
จัดสรรตัวเลข 4 ไบต์หรือ 32 บิต อย่างไรก็ตาม สิ่งนี้ไม่ได้มีบทบาทในตัวอย่างนี้ ดังนั้นในตัวอย่างนี้ เราจะถือว่าตัวเลขของเราเป็นหนึ่งไบต์ 
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
หลักที่สำคัญที่สุดคือศูนย์ ซึ่งหมายความว่าเรามีจำนวนบวก หากต้องการแปลงเป็นรหัสเพิ่มเติม:
-
เราเขียนตัวเลข -13 ในสิ่งที่เรียกว่า "รหัสโดยตรง" เมื่อต้องการทำเช่นนี้ ให้เปลี่ยนหลักที่สำคัญที่สุดของตัวเลขเป็น 1
ผลลัพธ์ของการดำเนินการ:10000000 0000000 0000000 00001101
-
ต่อไป เราจะกลับบิตทั้งหมด (เราเปลี่ยน 0 เป็น 1 และ 1 เป็น 0) ยกเว้นบิตเครื่องหมาย อันที่จริงเราได้เปลี่ยนมันไปแล้ว
ผลลัพธ์ของการกระทำ:11111111 11111111 11111111 11110010
(ใช่ ขั้นตอน 1 และ 2 สามารถรวมกันได้ แต่ควรคิดแบบนั้นจะดีกว่า)
- เพิ่ม 1 ให้กับตัวเลขผลลัพธ์
ผลลัพธ์ของการกระทำ:11111111 11111111 11111111 11110011
-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е.
- Поразрядный сдвиг вправо может сохранять знак (
>>
), а может — не сохранять (>>>
).
GO TO FULL VERSION