python ย้อนกลับรูปแบบไบนารีภายในจำนวนเต็ม

Sep 02 2020

มีความเป็นไปได้ที่รวดเร็วในการย้อนกลับเลขฐานสองใน python หรือไม่?

ตัวอย่าง: ฉันมีเลข 11 ในไบนารี 0000000000001011 ที่มี 16 บิต ตอนนี้ฉันกำลังค้นหาฟังก์ชันที่รวดเร็ว f ซึ่งส่งคืน 1101000000000000 (ทศนิยม 53248) ตารางการค้นหาไม่ใช่วิธีแก้ปัญหาเนื่องจากฉันต้องการให้ปรับขนาดเป็นตัวเลข 32 บิต ขอบคุณสำหรับความพยายามของคุณ.

แก้ไข:

การแสดง . ฉันทดสอบโค้ดสำหรับรูปแบบ 2 ^ 16 ทั้งหมดหลายครั้ง

  • ผู้ชนะคือตารางค้นหาบางส่วน: 30ms

  • ที่ 2 int(format(num, '016b')[::-1], 2)จากความคิดเห็น: 56ms

  • ที่ 3 x = ((x & 0x00FF) << 8) | (x >> 8): 65ms

  • ฉันไม่ได้คาดหวังว่าแนวทางของฉันจะช้าอย่างน่ากลัว แต่มันก็เป็นเช่นนั้น ประมาณ 320 มิลลิวินาที ปรับปรุงเล็กน้อยโดยใช้ + แทน | 300 มิลลิวินาที

  • bytes(str(num).encode('utf-8'))ต่อสู้เพื่อชิงอันดับที่ 2 แต่โค้ดไม่ได้ให้คำตอบที่ถูกต้อง ส่วนใหญ่เป็นเพราะฉันทำผิดโดยการแปลงเป็นจำนวนเต็มอีกครั้ง

ขอบคุณมากสำหรับข้อมูลของคุณ ฉันค่อนข้างประหลาดใจ

คำตอบ

3 HL Sep 02 2020 at 04:36

สิ่งนี้อาจเร็วกว่าโดยใช้ตารางการค้นหา 8 บิตขนาดเล็ก:

num = 11
# One time creation of 8bit lookup
rev = [int(format(b, '08b')[::-1], base=2) for b in range(256)]

# Run for each number to be flipped.
lower_rev = rev[num & 0xFF] << 8
upper_rev = rev[(num & 0xFF00) >> 8]
flipped = lower_rev + upper_rev
1 Ethan Sep 02 2020 at 03:55

ฉันคิดว่าคุณสามารถใช้การแบ่งส่วนเพื่อให้ได้สิ่งที่คุณกำลังมองหา:

b=bytes('0000000000001011'.encode('utf-8'))
>>> b
b'0000000000001011'
>>> b[::-1]
b'1101000000000000'
1 superbrain Sep 02 2020 at 04:27

มีสิ่งนี้ แต่ใน Python ดูเหมือนว่าจะช้ากว่าโซลูชันint-> str-> ของ Matthias ที่เสนอint

x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1)
x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2)
x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4)
x = ((x & 0x00FF) << 8) | (x >> 8)
1 DuDa Sep 02 2020 at 03:48

แนวทางปัจจุบันของฉันคือการเข้าถึงบิตผ่านการขยับบิตและการมาสก์และเปลี่ยนเป็นหมายเลขมิเรอร์จนกว่าจะถึงปลายทาง ฉันยังรู้สึกว่ายังมีช่องว่างให้ปรับปรุง

num = 11
print(format(num, '016b'))

right = num
left = 0
for i in range(16):
  tmp = right & 1
  left = (left << 1 ) | tmp
  right = right >> 1


print(format(left, '016b'))