Bitwise-OR เทียบกับการเพิ่มค่าสถานะ


16

ฉันเคยเห็นคนอื่นใช้ Bitwise-OR เพื่อรวมแฟล็กก่อนหน้านี้:

#define RUN 0x01
#define JUMP 0x02
#define SHOOT 0x04

const byte madPerson = RUN | JUMP | SHOOT;

นั่นเป็นวิธีที่ฉันทำ

แต่ฉันยังเห็นบางอย่าง (ไม่มาก) รวมธงโดยใช้การเพิ่ม:

#define RUN 0x01
#define JUMP 0x02
#define SHOOT 0x04

const byte madPerson = RUN + JUMP + SHOOT;

อันไหน "อ่าน" มากกว่า? (อันไหนที่คุณคิดว่าคนอื่นจะจำได้?) วิธี "มาตรฐาน" ในการทำคืออะไร? คุณชอบอันไหน


นี่คือคำถาม SO พิจารณาการใช้สิ่งที่ชอบ1<<0, 1<<1, 1<<2และอื่น ๆ เมื่อคุณมีแฟล็กจำนวนมากมันจะสามารถอ่านได้ง่ายขึ้นดูแลได้มากขึ้นและมีข้อผิดพลาดน้อยลง ตัวอย่างเช่นถ้าคุณบรรจุ 64 บิตของ int 64 บิตคุณต้องการหลีกเลี่ยงการพิมพ์ผิด :) วิธีที่คุณเป็นตัวแทน1ก็สำคัญเช่นกัน สำหรับจำนวนเต็ม 64 บิตใน VS2010 ฉันคิดว่ามันเป็น1UI64หรืออะไรแบบนั้น การใช้ประเภทผิดอาจกัดคุณ
งาน

3
@Job: ไม่ใช่คำถาม StackOverflow เนื่องจากมีการถามเกี่ยวกับความสามารถในการอ่านการจดจำการกำหนดค่าตามความชอบและแนวทางปฏิบัติที่ดีที่สุด ไม่มีคำตอบที่เป็นวัตถุประสงค์เดียวสำหรับมัน มันอยู่ที่นี่
Macneil

คำตอบ:


34

ค่าที่เหมาะสมหรือ

การเติมเป็นสิ่งที่อันตราย

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

#define PERSON 1 << 0
#define SPEAKS 1 << 1
#define SHOOTS 1 << 2
#define INVINCIBLE 1 << 3
const byte bandit = PERSON | SHOOTS;                    // 00000101
const byte angryBandit_add = bandit + SPEAKS + SHOOTS;  // 00001011 error
const byte angryBandit_or = bandit | SPEAKS | SHOOTS;   // 00000111 ok

หากคุณใช้angryBandit_addเกมของคุณตอนนี้จะมีข้อผิดพลาดเชิงตรรกะที่น่างงงวยจากการมีโจรโกรธที่ไม่สามารถยิงหรือฆ่าได้

หากคุณใช้ที่เลวร้ายที่สุดที่คุณจะต้องเป็นซ้ำซ้อนangryBandit_or| SHOOTS

สำหรับเหตุผลที่คล้ายกัน bitwise NOT นั้นปลอดภัยกว่าการลบสำหรับการลบค่าสถานะ


11

bitwise-OR บ่งบอกถึงเจตนาที่ชัดเจนยิ่งขึ้น

นอกจากนี้ระดับบิตหรือ OR ควรมีประสิทธิภาพมากขึ้น


+1 แน่นอนฉันยังคิดว่าหรือทำให้ชัดเจนยิ่งขึ้นว่าเป็นธง แต่เกี่ยวกับประสิทธิภาพมีภาษาที่การดำเนินการบิตช้าเช่น JavaScript ตัวเลขทั้งหมดเป็น 64 ลอยตัวผู้ประกอบการระดับบิตจำเป็นต้องทำการแปลงโดยปริยาย
Ivo Wetzel

1
จากตัวอย่างของ OP ฉันไม่คิดว่า ORs หนึ่งบรรทัดหรือมากกว่านั้นจะส่งผลเสียต่อความเร็วในการทำงานของโปรแกรม
มนุษย์ดีบุก

1
@Greg: โดยเฉพาะอย่างยิ่งตั้งแต่การคำนวณในตัวอย่างนั้นจะทำในเวลารวบรวม :-)
Carson63000

นอกเหนือจากการถ่ายทอดเจตนาเป็นเรื่องธรรมดาที่จะเห็นสิ่งนี้ในหลายภาษารวมถึง แต่ไม่ จำกัด เฉพาะ ADA, C #, Java ...
Ken Henderson

2
"ควร" เป็นคำที่ใหญ่มากในธุรกิจนี้ ในขณะที่ไม่น่าเป็นไปได้สูงที่คุณจะพบกับปัญหานี้ในวันนี้ แต่ฉันมีความทรงจำที่ชัดเจนเกี่ยวกับการทำงานกับโปรเซสเซอร์ที่ไม่มีคำสั่งแบบบิตหรือ OR คุณสามารถ bitwise-AND ในหนึ่งคำสั่งและคุณสามารถ bitwise-XOR ในการเรียนการสอนเดียว แต่ bitwise-OR ใช้สอง: bitwise ทันที - และ AND เพื่อปิด bit และ Bitwise-XOR ทันทีเพื่อเติมบิตที่เพิ่งล้างใหม่ ซึ่งแน่นอนตั้งไว้
John R. Strohm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.