ค่า“ (int) & ค่า 0x1, (int) & ค่า 0x2, (int) ค่า & 0x4, (int) ค่า & 0x8” หมายถึงอะไร "


11

รหัส

"value" มีค่าตั้งแต่ 0 ถึง 15 (ค่าที่เป็นไปได้) เมื่อใดที่จะเป็นไปตามเงื่อนไข 4 "ถ้า" ถ้าค่า (int) ของฉัน = 2 นี่หมายความว่า 0010 หรือไม่

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }

3
นั่นคือbitmasks ที่ตรวจสอบแต่ละบิตของvalue(อ่านif(value & 0x4)ว่า "Is bit 3 valueเซ็ต (= 1)) ในขณะที่คุณดูเหมือนมีปัญหาในการเข้าใจรหัสฉันถือว่ามันไม่ใช่ของคุณนี่ (และความจริงที่ว่าคุณไม่ได้ถาม สำหรับการตรวจสอบ) ทำให้คำถามนี้ปิดหัวข้อสำหรับCR.SE .
ไม่มีใคร

เพื่อความเข้าใจที่ดีขึ้นโค้ดที่คล้ายกันซึ่งถูกย้ายไปยัง C # จะใช้Enum.HasFlagวิธีทดสอบบิต ดู: Enum.HasFlag

คำตอบ:


12

แต่ละหมายเลขสามารถแสดงได้เช่นเดียวvalue = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...กับแต่ละ b ที่เป็น0หรือ1(นี่คือบิตของการแทนค่า) นี่คือการเป็นตัวแทนไบนารี

ไบนารี AND ( &) รับbคู่แต่ละคู่ที่ชาญฉลาดและมีประสิทธิภาพและกับพวกเขา นี่มีเอาต์พุตต่อไปนี้:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

การใช้กำลัง 2 (ซึ่งมีเพียงบิตเดียว) เราสามารถแยกและทดสอบแต่ละบิต:

  • value & 1เป็นจริงเมื่อvalueเป็นเลขคี่ {1, 3, 5, 7, 9, 11, 13, 15}

  • value & 2เป็นจริงเมื่อvalue/2เป็นเลขคี่ {2, 3, 6, 7, 10, 11, 14, 15}

  • value & 4เป็นจริงเมื่อvalue/4เป็นเลขคี่ {4, 5, 6, 7, 12, 13, 14, 15}

  • value & 8เป็นจริงเมื่อvalue/8เป็นเลขคี่ {8, 9, 10, 11, 12, 13, 14, 15}

prefex 0x บนตัวเลขหมายความว่ามันควรจะตีความว่าเป็นเลขฐานสิบหก มันค่อนข้างฟุ่มเฟือยเมื่อคุณไปถึง 0x8 แต่บอกผู้ดูแลว่ามันอาจใช้เป็นบิตมาสก์


1
ข้อความอาจบอกว่ามันสามารถขยายไปถึงตัวเลขทั้งหมดซึ่งไม่เป็นความจริง: 8/6เป็นคี่ในขณะที่8&6ผลผลิตเท็จ
Sjoerd

@ Joeerd นั่นเป็นสาเหตุที่ฉันพูดว่า "powers of 2"
ratchet freak

5

คำสั่ง if-if เหล่านี้ตรวจสอบว่ามีการvalueตั้งค่าบิตเฉพาะหรือไม่

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

ดังนั้นเมื่อคุณทำการคำนวณvalue & 0x4คุณจะได้รับไบนารี00000000หรือไบนารี00000100ขึ้นอยู่กับว่าบิตที่ 3 valueเป็น1หรือ0ไม่ การประเมินครั้งแรกเป็นfalseและครั้งที่สองเพื่อtrueให้มีการเรียกใช้งาน if-block เฉพาะสำหรับค่าที่บิตที่ 3 ถูกตั้งค่า


1

มีสองสิ่งที่น่าสนใจที่ควรทราบที่นี่

ครั้งแรกนี่เป็นรูปแบบทั่วไปสำหรับการตรวจสอบแต่ละค่า 4 บิตต่ำของค่าอินทิกรัล เงื่อนไข if ตรงกันหากตั้งค่าบิตที่สอดคล้องกัน สำหรับค่า 2 รูปแบบบิตคือ 0010

คำถามที่น่าสนใจอื่น ๆ คือทำไม(int)นักแสดง? นอกเหนือจากรูปแบบที่ไม่ดีของการใช้ C-casts ใน C ++ แล้วยังไม่มีค่าจำนวนเต็มหรืออักขระที่ต้องใช้ในการส่ง บูลไม่มีเหตุผลคู่ / ลอยจะถูกแปลงเป็นจำนวนเต็มชั่วคราวและมันจะผิดปกติในการใช้ค่าตามตัวอักษรเพื่อทดสอบ enum มันอาจสมเหตุสมผลกับตัวชี้ แต่นั่นเป็นการใช้งานที่พิเศษมาก สรุป: นักแสดงไม่สมเหตุสมผล

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