ตัวดำเนินการเปลี่ยนบิตทำสิ่งที่ชื่อของพวกเขามีความหมาย พวกเขาเปลี่ยนบิต ต่อไปนี้เป็นคำแนะนำสั้น ๆ (หรือไม่สั้น) เกี่ยวกับตัวดำเนินการกะที่แตกต่างกัน
ผู้ประกอบการ
>> เป็นตัวดำเนินการทางด้านขวาของเลขคณิต (หรือที่ลงชื่อ)
>>> เป็นตัวดำเนินการ shift ที่เหมาะสม (หรือไม่ได้ลงชื่อ) ตรรกะ
<< เป็นโอเปอเรเตอร์กะซ้ายและตอบสนองความต้องการของการเลื่อนทั้งแบบลอจิคัลและเลขคณิต
ทั้งหมดของผู้ประกอบการเหล่านี้สามารถนำไปใช้กับค่าจำนวนเต็ม ( int, longอาจจะเป็นshortและbyteหรือchar) ในบางภาษาใช้ประกอบการเปลี่ยนไปใช้ประเภทข้อมูลใด ๆ ที่มีขนาดเล็กกว่าโดยอัตโนมัติปรับขนาดตัวถูกดำเนินการที่จะเป็นintint
โปรดทราบว่า<<<ไม่ใช่ตัวดำเนินการเนื่องจากจะซ้ำซ้อน
นอกจากนี้ทราบว่าC และ C ++ ไม่เห็นความแตกต่างระหว่างผู้ประกอบการเปลี่ยนแปลงทางด้านขวา พวกเขาให้บริการเฉพาะ>>ผู้ประกอบการและพฤติกรรมการเปลี่ยนด้านขวาเป็นการใช้งานที่กำหนดไว้สำหรับประเภทที่ลงนาม คำตอบที่เหลือใช้ตัวดำเนินการ C # / Java
(ในการใช้งาน C และ C ++ ที่สำคัญทั้งหมดรวมถึง GCC และ Clang / LLVM >>สำหรับประเภทที่ลงนามคือเลขคณิตรหัสบางอย่างถือว่านี่ แต่มันไม่ใช่สิ่งที่รับประกันมาตรฐาน แต่ก็ไม่ได้กำหนดแต่มาตรฐานนั้นต้องมีการนำไปใช้เพื่อกำหนด อีกวิธีหนึ่งอย่างไรก็ตามการเลื่อนซ้ายของตัวเลขที่มีเครื่องหมายลบนั้นเป็นพฤติกรรมที่ไม่ได้กำหนดไว้ (ล้นจำนวนเต็มที่ลงนามแล้ว) ดังนั้นหากคุณไม่จำเป็นต้องใช้การเลื่อนขวาแบบเลขคณิตคุณควรทำการเปลี่ยนบิตด้วยประเภทที่ไม่ได้ลงนาม)
เลื่อนไปทางซ้าย (<<)
จำนวนเต็มถูกเก็บไว้ในหน่วยความจำเป็นชุดของบิต ตัวอย่างเช่นหมายเลข 6 ที่จัดเก็บเป็น 32 บิตintจะเป็น:
00000000 00000000 00000000 00000110
การเลื่อนรูปแบบบิตนี้ไปทางซ้ายหนึ่งตำแหน่ง ( 6 << 1) จะส่งผลให้หมายเลข 12:
00000000 00000000 00000000 00001100
อย่างที่คุณเห็นตัวเลขได้เลื่อนไปทางซ้ายหนึ่งตำแหน่งและตัวเลขสุดท้ายทางด้านขวาเต็มไปด้วยศูนย์ นอกจากนี้คุณยังอาจจะทราบว่าการขยับซ้ายจะเทียบเท่ากับการคูณโดยอำนาจของ 2 ดังนั้น6 << 1จะเทียบเท่ากับ6 * 2และเทียบเท่ากับ6 << 3 6 * 8คอมไพเลอร์การปรับให้เหมาะสมที่ดีจะแทนที่การคูณด้วยการเลื่อนเมื่อทำได้
การขยับแบบไม่เป็นวงกลม
โปรดทราบว่าสิ่งเหล่านี้ไม่ใช่การเปลี่ยนแปลงแบบวงกลม เลื่อนค่านี้ไปทางซ้ายทีละตำแหน่ง ( 3,758,096,384 << 1):
11100000 00000000 00000000 00000000
ผลลัพธ์ใน 3,221,225,472:
11000000 00000000 00000000 00000000
ตัวเลขที่ได้รับการเลื่อน "ปิดท้าย" จะหายไป มันไม่ได้พันรอบ
ลอจิกกะขวา (>>>)
การเลื่อนขวาแบบลอจิคัลคือการสนทนาไปทางซ้าย แทนที่จะขยับบิตไปทางซ้ายพวกเขาก็เลื่อนไปทางขวา ตัวอย่างเช่นการขยับหมายเลข 12:
00000000 00000000 00000000 00001100
ไปทางขวาโดยตำแหน่งหนึ่ง ( 12 >>> 1) จะได้รับ 6 ดั้งเดิมคืนของเรา:
00000000 00000000 00000000 00000110
ดังนั้นเราจะเห็นว่าการขยับไปทางขวาเทียบเท่ากับการหารด้วยพลังของ 2
บิตที่หายไปจะหายไป
อย่างไรก็ตามกะไม่สามารถเรียกคืนบิต "ที่หายไป" ได้ ตัวอย่างเช่นถ้าเราเปลี่ยนรูปแบบนี้:
00111000 00000000 00000000 00000110
ทางซ้าย 4 ตำแหน่ง ( 939,524,102 << 4) เราได้รับ 2,147,483,744:
10000000 00000000 00000000 01100000
แล้วขยับกลับ ( (939,524,102 << 4) >>> 4) เราจะได้ 134,217,734:
00001000 00000000 00000000 00000110
เราไม่สามารถคืนค่าเดิมของเราได้เมื่อเราทำบิตหาย
การเลื่อนขวาของเลขคณิต (>>)
การเลื่อนขวาของเลขคณิตนั้นเหมือนกับการเลื่อนขวาแบบลอจิคัลยกเว้นการเว้นระยะห่างจากศูนย์มันจะมีบิตที่สำคัญที่สุด นี่เป็นเพราะบิตที่สำคัญที่สุดคือบิตเครื่องหมายหรือบิตที่แยกความแตกต่างระหว่างจำนวนบวกและลบ ด้วยการเติมด้วยบิตที่สำคัญที่สุดการเลื่อนขวาของเลขคณิตจะเป็นการรักษาเครื่องหมาย
ตัวอย่างเช่นหากเราตีความรูปแบบบิตนี้เป็นจำนวนลบ:
10000000 00000000 00000000 01100000
เรามีหมายเลข -2,147,483,552 การเลื่อนสิ่งนี้ไปทางขวา 4 ตำแหน่งพร้อมการเปลี่ยนแปลงทางคณิตศาสตร์ (-2,147,483,552 >> 4) จะทำให้เรา:
11111000 00000000 00000000 00000110
หรือหมายเลข -134,217,722
ดังนั้นเราจะเห็นว่าเราได้รักษาเครื่องหมายของตัวเลขติดลบของเราไว้โดยใช้การเลื่อนขวาแบบเลขคณิตแทนการเลื่อนขวาแบบตรรกะ และอีกครั้งเราจะเห็นว่าเรากำลังทำการหารด้วยอำนาจของ 2