การทำงานและการใช้งาน Bitwise


103

พิจารณารหัสนี้:

x = 1        # 0001
x << 2       # Shift left 2 bits: 0100
# Result: 4

x | 2        # Bitwise OR: 0011
# Result: 3

x & 1        # Bitwise AND: 0001
# Result: 1

ฉันสามารถเข้าใจตัวดำเนินการทางคณิตศาสตร์ใน Python (และภาษาอื่น ๆ ) ได้ แต่ฉันไม่เคยเข้าใจตัวดำเนินการ 'bitwise' ค่อนข้างดี ในตัวอย่างด้านบน (จากหนังสือ Python) ฉันเข้าใจการเลื่อนไปทางซ้าย แต่ไม่ใช่อีกสองตัว

นอกจากนี้ตัวดำเนินการระดับบิตใช้สำหรับอะไร? ฉันขอขอบคุณตัวอย่างบางส่วน


11
สิ่งนี้อาจเป็นที่สนใจ: stackoverflow.com/questions/276706/what-are-bitwise-operators
outis

สิ่งนี้อาจเป็นที่สนใจ: stackoverflow.com/questions/8556206/what-does-mean-in-python
Philippe Oger

คำตอบ:


163

ตัวดำเนินการ Bitwise คือตัวดำเนินการที่ทำงานกับค่าหลายบิต แต่มีแนวคิดทีละบิต

  • ANDคือ 1 ก็ต่อเมื่ออินพุตทั้งสองเป็น 1 มิฉะนั้นจะเป็น 0
  • ORคือ 1 ถ้าอินพุตหนึ่งหรือทั้งสองอินพุตเป็น 1 มิฉะนั้นจะเป็น 0
  • XORคือ 1 ก็ต่อเมื่ออินพุตตัวใดตัวหนึ่งเป็น 1 เท่านั้นมิฉะนั้นจะเป็น 0
  • NOT คือ 1 ก็ต่อเมื่ออินพุตเป็น 0 มิฉะนั้นจะเป็น 0

สิ่งเหล่านี้มักจะแสดงเป็นตารางความจริงได้ดีที่สุด ความเป็นไปได้ในการป้อนข้อมูลอยู่ที่ด้านบนและด้านซ้ายบิตผลลัพธ์คือหนึ่งในสี่ (สองในกรณีที่ไม่ใช่เนื่องจากมีเพียงอินพุตเดียว) ที่แสดงที่จุดตัดของอินพุต

AND | 0 1     OR | 0 1     XOR | 0 1    NOT | 0 1
----+-----    ---+----     ----+----    ----+----
 0  | 0 0      0 | 0 1       0 | 0 1        | 1 0
 1  | 0 1      1 | 1 1       1 | 1 0

ตัวอย่างหนึ่งคือถ้าคุณต้องการเพียง 4 บิตล่างของจำนวนเต็มคุณและมันด้วย 15 (ไบนารี 1111) ดังนั้น:

    201: 1100 1001
AND  15: 0000 1111
------------------
 IS   9  0000 1001

ศูนย์บิตใน 15 ในกรณีนั้นทำหน้าที่เป็นตัวกรองได้อย่างมีประสิทธิภาพบังคับให้บิตในผลลัพธ์เป็นศูนย์เช่นกัน

นอกจากนี้>>และ<<มักจะรวมเป็นตัวดำเนินการแบบบิตและพวกเขาจะ "เลื่อน" ค่าตามลำดับไปทางขวาและซ้ายด้วยจำนวนบิตที่แน่นอนทิ้งบิตที่ม้วนปลายที่คุณกำลังขยับไปและป้อนเป็นศูนย์บิตที่ ปลาย ๆ

ตัวอย่างเช่น:

1001 0101 >> 2 gives 0010 0101
1111 1111 << 4 gives 1111 0000

โปรดทราบว่าการเลื่อนไปทางซ้ายใน Python นั้นผิดปกติเนื่องจากไม่ได้ใช้ความกว้างคงที่ซึ่งบิตจะถูกละทิ้ง - ในขณะที่หลายภาษาใช้ความกว้างคงที่ตามประเภทข้อมูล Python เพียงแค่ขยายความกว้างเพื่อรองรับบิตพิเศษ เพื่อให้ได้พฤติกรรมการทิ้งใน Python คุณสามารถทำตามการเลื่อนไปทางซ้ายด้วยการหมุนตามเข็มนาฬิกาandเช่นค่า8 บิตเลื่อนไปทางซ้ายสี่บิต:

bits8 = (bits8 << 4) & 255

โดยที่ในใจตัวอย่างของผู้ประกอบการระดับบิตอีกคือถ้าคุณมีสองค่า 4 บิตที่คุณต้องการที่จะแพ็คเป็นหนึ่งใน 8 บิตคุณสามารถใช้ทั้งสามของผู้ประกอบการของคุณ ( left-shift, andและor):

packed_val = ((val1 & 15) << 4) | (val2 & 15)
  • การ& 15ดำเนินการจะทำให้แน่ใจว่าทั้งสองค่ามีเพียง 4 บิตที่ต่ำกว่า
  • << 4เป็นกะ 4 บิตซ้ายไปย้ายval1เข้ามาอยู่อันดับ 4 บิตของมูลค่า 8 บิต
  • |เพียงรวมทั้งสองเข้าด้วยกัน

ถ้าval1เป็น 7 และval2เป็น 4:

                val1            val2
                ====            ====
 & 15 (and)   xxxx-0111       xxxx-0100  & 15
 << 4 (left)  0111-0000           |
                  |               |
                  +-------+-------+
                          |
| (or)                0111-0100

43

การใช้งานทั่วไปอย่างหนึ่ง:

| ใช้เพื่อตั้งค่าบิตเป็น 1

& ใช้เพื่อทดสอบหรือล้างข้อมูลเล็กน้อย

  • ตั้งค่าบิต (โดยที่ n คือจำนวนบิตและ 0 เป็นบิตที่มีนัยสำคัญน้อยที่สุด):

    unsigned char a |= (1 << n);

  • เคลียร์หน่อย:

    unsigned char b &= ~(1 << n);

  • สลับเล็กน้อย:

    unsigned char c ^= (1 << n);

  • ทดสอบสักหน่อย:

    unsigned char e = d & (1 << n);

ยกตัวอย่างรายการของคุณ:

x | 2ใช้เพื่อตั้งค่าบิต 1 xเป็น 1

x & 1ใช้เพื่อทดสอบว่าบิต 0 xเป็น 1 หรือ 0


38

ตัวดำเนินการระดับบิตใช้สำหรับอะไร? ฉันขอขอบคุณตัวอย่างบางส่วน

หนึ่งในการใช้งาน bitwise ที่พบบ่อยที่สุดคือการแยกวิเคราะห์สีฐานสิบหก

ตัวอย่างเช่นนี่คือฟังก์ชันPythonที่ยอมรับ String like #FF09BEและส่งคืนทูเปิลของค่าสีแดงสีเขียวและสีน้ำเงิน

def hexToRgb(value):
    # Convert string to hexadecimal number (base 16)
    num = (int(value.lstrip("#"), 16))

    # Shift 16 bits to the right, and then binary AND to obtain 8 bits representing red
    r = ((num >> 16) & 0xFF)

    # Shift 8 bits to the right, and then binary AND to obtain 8 bits representing green
    g = ((num >> 8) & 0xFF)

    # Simply binary AND to obtain 8 bits representing blue
    b = (num & 0xFF)
    return (r, g, b)

ฉันรู้ว่ามีวิธีที่มีประสิทธิภาพมากกว่าในการบรรลุสิ่งนี้ แต่ฉันเชื่อว่านี่เป็นตัวอย่างที่กระชับจริงๆซึ่งแสดงให้เห็นทั้งการเลื่อนและการดำเนินการบูลีนแบบบิต


15

ฉันคิดว่าส่วนที่สองของคำถาม:

นอกจากนี้ตัวดำเนินการระดับบิตใช้สำหรับอะไร? ฉันขอขอบคุณตัวอย่างบางส่วน

ได้รับการแก้ไขเพียงบางส่วนเท่านั้น นี่คือสองเซ็นต์ของฉันในเรื่องนั้น

การใช้งาน Bitwise ในภาษาโปรแกรมมีบทบาทพื้นฐานเมื่อต้องจัดการกับแอปพลิเคชันจำนวนมาก การประมวลผลระดับต่ำเกือบทั้งหมดต้องทำโดยใช้การดำเนินการประเภทนี้

ในแอปพลิเคชันทั้งหมดที่ต้องการส่งข้อมูลระหว่างสองโหนดเช่น:

  • เครือข่ายคอมพิวเตอร์

  • แอปพลิเคชั่นโทรคมนาคม (โทรศัพท์เคลื่อนที่การสื่อสารผ่านดาวเทียม ฯลฯ )

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

โดยทั่วไปเมื่อจัดการกับแอปพลิเคชันประเภทนั้นจะมี API ให้คุณจึงไม่ต้องจัดการกับรายละเอียดทั้งหมดเหล่านั้น ตัวอย่างเช่นภาษาโปรแกรมสมัยใหม่ทั้งหมดมีไลบรารีสำหรับการเชื่อมต่อซ็อกเก็ตดังนั้นคุณจึงไม่จำเป็นต้องสร้างเฟรมการสื่อสาร TCP / IP แต่ลองนึกถึงคนดีๆที่ตั้งโปรแกรม API ให้คุณพวกเขาต้องจัดการกับการสร้างเฟรมอย่างแน่นอน โดยใช้การดำเนินการระดับบิตทุกชนิดเพื่อย้อนกลับไปมาจากระดับต่ำไปจนถึงการสื่อสารระดับสูง

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

แอปพลิเคชั่นระดับต่ำที่แตกต่างกันมากอีกอย่างหนึ่งคือเมื่อคุณต้องการควบคุมฮาร์ดแวร์โดยใช้พอร์ต (แบบโบราณ) บางพอร์ตเช่นพอร์ตขนานและพอร์ตอนุกรม พอร์ตนี้ถูกควบคุมโดยการตั้งค่าไบต์บางส่วนและแต่ละบิตของไบต์นั้นมีความหมายเฉพาะในแง่ของคำแนะนำสำหรับพอร์ตนั้น (ดูตัวอย่างเช่นhttp://en.wikipedia.org/wiki/Parallel_port ) หากคุณต้องการสร้างซอฟต์แวร์ที่ทำอะไรบางอย่างกับฮาร์ดแวร์นั้นคุณจะต้องใช้การดำเนินการในระดับบิตเพื่อแปลคำสั่งที่คุณต้องการเรียกใช้เป็นไบต์ที่พอร์ตเข้าใจ

ตัวอย่างเช่นหากคุณมีปุ่มทางกายภาพบางปุ่มที่เชื่อมต่อกับพอร์ตขนานเพื่อควบคุมอุปกรณ์อื่น ๆ นี่คือบรรทัดของรหัสที่คุณสามารถพบได้ในซอฟต์แอปพลิเคชัน:

read = ((read ^ 0x80) >> 4) & 0x0f; 

หวังว่านี่จะมีส่วนช่วย


ฉันจะเพิ่มen.wikipedia.org/wiki/Bit_bangingเป็นอีกช่องทางหนึ่งในการสำรวจโดยเฉพาะอย่างยิ่งหากอ่านเกี่ยวกับพอร์ตขนานและพอร์ตอนุกรมเป็นตัวอย่างที่การดำเนินการในระดับบิตจะมีประโยชน์
แดน

6

ฉันหวังว่าสิ่งนี้จะทำให้สองคนนี้กระจ่าง:

x | 2

0001 //x
0010 //2

0011 //result = 3

x & 1

0001 //x
0001 //1

0001 //result = 1

4
อ๊ะ ... พยายามเป็นปืนที่เร็วที่สุดในตะวันตก .... จบลงด้วยการเป็นคนงี่เง่าที่ไม่รู้จักไบนารีเป็นเวลาสอง :( แก้ไขแล้ว
Amarghosh

1
x & 1ไม่แสดงผลเช่นเดียวกับที่x & 2จะ
dansalmo

5

คิดว่า 0 เป็นเท็จและ 1 เป็นจริง จากนั้น bitwise และ (&) และหรือ (|) จะทำงานเหมือนกับปกติและและหรือยกเว้นพวกเขาทำบิตทั้งหมดในค่าพร้อมกัน โดยทั่วไปคุณจะเห็นค่าเหล่านี้ใช้สำหรับแฟล็กหากคุณมีตัวเลือก 30 ตัวที่สามารถตั้งค่าได้ (พูดเป็นรูปแบบการวาดบนหน้าต่าง) คุณไม่ต้องการส่งผ่านค่าบูลีนแยกกัน 30 ค่าเพื่อตั้งค่าหรือยกเลิกการตั้งค่าแต่ละค่าดังนั้นคุณจึงใช้ | เพื่อรวมตัวเลือกเป็นค่าเดียวจากนั้นคุณใช้ & เพื่อตรวจสอบว่าแต่ละตัวเลือกถูกตั้งค่าหรือไม่ รูปแบบการส่งผ่านแฟล็กนี้ถูกใช้อย่างมากโดย OpenGL เนื่องจากแต่ละบิตเป็นแฟล็กที่แยกจากกันคุณจะได้รับค่าแฟล็กจากพาวเวอร์ของสอง (aka ตัวเลขที่มีชุดบิตเดียวเท่านั้น) 1 (2 ^ 0) 2 (2 ^ 1) 4 (2 ^ 2) 8 (2 ^ 3) กำลังสองจะบอกคุณว่าบิตใดถูกตั้งค่าหากแฟล็กเปิดอยู่

นอกจากนี้หมายเหตุ 2 = 10 ดังนั้น x | 2 คือ 110 (6) ไม่ใช่ 111 (7) หากไม่มีบิตใดทับซ้อนกัน (ซึ่งเป็นจริงในกรณีนี้) | ทำหน้าที่เหมือนการเพิ่ม


5

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

เมื่อเร็ว ๆ นี้ฉันเคยเห็นคนใช้ x << 1 และ x >> 1 ในการเพิ่มเป็นสองเท่าและครึ่งหนึ่งแม้ว่าฉันจะไม่แน่ใจว่าพวกเขาแค่พยายามฉลาดหรือว่ามีข้อได้เปรียบที่แตกต่างจากตัวดำเนินการปกติจริงๆ


1
ฉันไม่รู้เกี่ยวกับ python แต่ในภาษาระดับล่างเช่น C หรือแม้แต่แอสเซมบลีที่ต่ำกว่านั้นการกะบิตมีประสิทธิภาพมากกว่า หากต้องการดูความแตกต่างคุณสามารถเขียนโปรแกรมใน C โดยทำในแต่ละวิธีและคอมไพล์เป็นรหัสแอสเซมบลี (หรือถ้าคุณรู้จักแอสเซมบลี lang คุณก็คงจะรู้แล้ว :)) ดูความแตกต่างของจำนวนคำแนะนำ
0xc0de

2
ข้อโต้แย้งของฉันเกี่ยวกับการใช้ตัวดำเนินการกะบิตคือคอมไพเลอร์ที่ทันสมัยส่วนใหญ่น่าจะเพิ่มประสิทธิภาพการดำเนินการทางคณิตศาสตร์อยู่แล้วดังนั้นความฉลาดจึงเป็นสิ่งที่ดีที่สุดหรือแย่ที่สุดในการต่อสู้กับคอมไพเลอร์ ฉันไม่มีความเชี่ยวชาญในการออกแบบ C, คอมไพเลอร์หรือ CPU ดังนั้นอย่าคิดว่าฉันถูกต้อง :)
P. Stallworth

ควรจะสูงกว่านี้ ฉันต้องจัดการกับโค้ดบางอย่างที่ใช้ตัวดำเนินการแบบบิตด้วยวิธีนั้นและคำตอบนั้นช่วยให้ฉันหาสิ่งต่างๆได้
Philippe Oger

4

ชุด

ชุดสามารถรวมกันได้โดยใช้การดำเนินการทางคณิตศาสตร์

  • ตัวดำเนินการยูเนี่ยน|รวมสองชุดเพื่อสร้างชุดใหม่ที่มีรายการในอย่างใดอย่างหนึ่ง
  • ตัวดำเนินการจุดตัด&รับรายการเฉพาะในทั้งสองอย่าง
  • ตัวดำเนินการความแตกต่าง-รับรายการในชุดแรก แต่ไม่ได้รับในชุดที่สอง
  • ตัวดำเนินการผลต่างแบบสมมาตร^รับรายการในชุดใดชุดหนึ่ง แต่ไม่ใช่ทั้งสองอย่าง

ลองด้วยตัวคุณเอง:

first = {1, 2, 3, 4, 5, 6}
second = {4, 5, 6, 7, 8, 9}

print(first | second)

print(first & second)

print(first - second)

print(second - first)

print(first ^ second)

ผลลัพธ์:

{1, 2, 3, 4, 5, 6, 7, 8, 9}

{4, 5, 6}

{1, 2, 3}

{8, 9, 7}

{1, 2, 3, 7, 8, 9}

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

คำถามจะถามว่า "ตัวดำเนินการบิตไวด์ใช้สำหรับอะไร" คำตอบนี้ให้การใช้งานตัวดำเนินการระดับบิตที่เป็นที่รู้จักน้อยกว่า แต่มีประโยชน์มาก
Taegyung

3

ตัวอย่างนี้จะแสดงการดำเนินการสำหรับค่า 2 บิตทั้งสี่ค่า:

10 | 12

1010 #decimal 10
1100 #decimal 12

1110 #result = 14

10 & 12

1010 #decimal 10
1100 #decimal 12

1000 #result = 8

นี่คือตัวอย่างการใช้งานตัวอย่างหนึ่ง:

x = raw_input('Enter a number:')
print 'x is %s.' % ('even', 'odd')[x&1]

2

การใช้งานทั่วไปอีกกรณีหนึ่งคือการจัดการ / ทดสอบการอนุญาตไฟล์ ดูโมดูลสถิติหลาม: http://docs.python.org/library/stat.html

ตัวอย่างเช่นหากต้องการเปรียบเทียบสิทธิ์ของไฟล์กับชุดสิทธิ์ที่ต้องการคุณสามารถทำสิ่งต่อไปนี้

import os
import stat

#Get the actual mode of a file
mode = os.stat('file.txt').st_mode

#File should be a regular file, readable and writable by its owner
#Each permission value has a single 'on' bit.  Use bitwise or to combine 
#them.
desired_mode = stat.S_IFREG|stat.S_IRUSR|stat.S_IWUSR

#check for exact match:
mode == desired_mode
#check for at least one bit matching:
bool(mode & desired_mode)
#check for at least one bit 'on' in one, and not in the other:
bool(mode ^ desired_mode)
#check that all bits from desired_mode are set in mode, but I don't care about 
# other bits.
not bool((mode^desired_mode)&desired_mode)

ฉันโยนผลลัพธ์เป็นบูลีนเพราะฉันสนใจ แต่ความจริงหรือความเท็จ แต่มันจะเป็นแบบฝึกหัดที่คุ้มค่าในการพิมพ์ค่า bin () สำหรับแต่ละค่า


1
คุณผิดในตัวอย่างที่แล้ว ลักษณะที่ปรากฏมีดังนี้: not bool((mode ^ desired_mode) & 0777). หรือ not (mode & 0777) ^ desired_mode == 0(ง่ายต่อการเข้าใจ): และจะเหลือเฉพาะบิตที่น่าสนใจ XOR จะตรวจสอบว่าบิตที่ต้องการทั้งหมดถูกตั้งค่าไว้ อย่างชัดเจนเปรียบเทียบมีความหมายมากกว่า== 0 bool()
Vadim Fint

ฉันไม่คิดว่านี่เป็นเรื่องเฉพาะสำหรับการใช้งานไฟล์ ยกตัวอย่างเช่นใน PyQt setWindowFlagsคุณทำบางสิ่งบางอย่างที่คล้ายกันสำหรับ ตัวอย่าง: setWindowFlags(SplashScreen | WindowStaysOnTopHint). ฉันยังคงพบความสับสนเนื่องจากดูเหมือนว่าการสลับที่คุณกำลังตั้งค่าเป็น "เปิด" จึงดูเหมือนจะใช้งานง่ายกว่าสำหรับ "และ" ในกรณีเช่นนี้
eric

2

การแทนค่าบิตของจำนวนเต็มมักใช้ในการคำนวณทางวิทยาศาสตร์เพื่อแสดงอาร์เรย์ของข้อมูลจริง - เท็จเนื่องจากการดำเนินการในระดับบิตนั้นเร็วกว่าการวนซ้ำผ่านอาร์เรย์ของบูลีนมาก (ภาษาระดับสูงกว่าอาจใช้แนวคิดของบิตอาร์เรย์)

ตัวอย่างที่ดีและค่อนข้างเรียบง่ายนี้คือวิธีแก้ปัญหาทั่วไปของเกม Nim ลองดูที่เป็นงูหลามโค้ดบนหน้าวิกิพีเดีย ทำให้ใช้บิตพิเศษเฉพาะหรือ^.


1

อาจจะมีวิธีที่ดีกว่าที่จะหาที่องค์ประกอบอาร์เรย์อยู่ระหว่างสองค่า แต่เป็นตัวอย่างนี้แสดงให้เห็นว่าการและผลงานที่นี่ในขณะที่และไม่ได้

import numpy as np
a=np.array([1.2, 2.3, 3.4])
np.where((a>2) and (a<3))      
#Result: Value Error
np.where((a>2) & (a<3))
#Result: (array([1]),)

1

ฉันไม่เห็นมันกล่าวถึงตัวอย่างนี้จะแสดงการดำเนินการ (-) ทศนิยมสำหรับค่า 2 บิต: AB (เฉพาะในกรณีที่ A มี B)

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

111 #decimal 7
-
100 #decimal 4
--------------
011 #decimal 3

ด้วย python: 7 & ~ 4 = 3 (ลบออกจาก 7 บิตที่แสดงถึง 4)

001 #decimal 1
-
100 #decimal 4
--------------
001 #decimal 1

ด้วย python: 1 & ~ 4 = 1 (ลบออกจาก 1 บิตที่แสดงถึง 4 - ในกรณีนี้ 1 ไม่ใช่ 'มี' 4) ..


0

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

>>> import bitstring
>>> bitstring.BitArray(bytes='ABCDEFGHIJKLMNOPQ') << 4
BitArray('0x142434445464748494a4b4c4d4e4f50510')
>>> bitstring.BitArray(hex='0x4142434445464748494a4b4c4d4e4f5051') << 4
BitArray('0x142434445464748494a4b4c4d4e4f50510')


0

ในการพลิกบิต (เช่นส่วนเติมเต็ม / กลับด้าน 1) คุณสามารถทำสิ่งต่อไปนี้:

เนื่องจากค่า ExORed กับ 1s ทั้งหมดจะทำให้เกิดการผกผันสำหรับความกว้างบิตที่กำหนดคุณสามารถใช้ ExOR เพื่อกลับด้านได้

In Binary
a=1010 --> this is 0xA or decimal 10
then 
c = 1111 ^ a = 0101 --> this is 0xF or decimal 15
-----------------
In Python
a=10
b=15
c = a ^ b --> 0101
print(bin(c)) # gives '0b101'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.