[英]Reversibly encode two large integers of different bit lengths into one integer
由於n是固定的,所以問題很簡單:將 ( a , b ) 編碼為a •2 n + b 。
如果m和n不固定,則問題是不可能的,因為它要求我們將(兩位a ,一位b )和(一位a ,兩位b )都編碼為三位,這意味着我們必須編碼十二種可能性 (0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3) ), (2, 0), (2, 1), (3, 0), (3, 1) 三種比特的八種組合,這是不可能的。
該解決方案使用基本的位移位和位提取。 使用位運算應該比使用更高級別的運算(例如求冪和乘法)更快。
基本解決方案與特殊情況下的解決方案大致相同,因為在任何一種情況下都只需要一個整數的最大位長度。 然而,測試並非如此。
from typing import Tuple
import unittest
class IntMerger:
"""Reversibly encode two integers into a single integer.
Only the first integer can be signed (possibly negative). The second
integer must be unsigned (always non-negative).
In the merged integer, the left bits are of the first input integer, and
the right bits are of the second input integer.
"""
# Ref: https://stackoverflow.com/a/54164324/
def __init__(self, num_bits_int2: int):
"""
:param num_bits_int2: Max bit length of second integer.
"""
self._num_bits_int2: int = num_bits_int2
self._max_int2: int = self._max_int(self._num_bits_int2)
@staticmethod
def _max_int(num_bits: int) -> int:
return (1 << num_bits) - 1
def merge(self, int1: int, int2: int) -> int:
return (int1 << self._num_bits_int2) | int2
def split(self, int12: int) -> Tuple[int, int]:
int1 = int12 >> self._num_bits_int2
int2 = int12 & self._max_int2
return int1, int2
class TestIntMerger(unittest.TestCase):
def test_intmerger(self):
max_num_bits = 8
for num_bits_int1 in range(max_num_bits + 1):
for num_bits_int2 in range(max_num_bits + 1):
expected_merged_max_num_bits = num_bits_int1 + num_bits_int2
merger = IntMerger(num_bits_int2)
maxint1 = (+1 << num_bits_int1) - 1
minint1 = (-1 << num_bits_int1) + 1
for int1 in range(minint1, maxint1 + 1):
for int2 in range(1 << num_bits_int2):
int12 = merger.merge(int1, int2)
# print(f'{int1} ({num_bits_int1}b), {int2} ({num_bits_int2}b) = {int12} ({int12.bit_length()}b)')
self.assertLessEqual(int12.bit_length(), expected_merged_max_num_bits)
self.assertEqual((int1, int2), merger.split(int12))
self.assertEqual(int12.bit_length(), expected_merged_max_num_bits)
if __name__ == '__main__':
unittest.main()
用法示例:
>>> merger = IntMerger(12)
>>> merger.merge(13, 8)
53256
>>> merger.split(_)
(13, 8)
>>> merger.merge(-13, 8)
-53240
>>> merger.split(_)
(-13, 8)
如果您絕對必須具有完全可逆性,則需要放寬至少一個隱含的初始條件(因為如果您不單獨記住這些數字中的任何一個並且響應位長 R 小於 m+n,則您將不可撤銷地失去完全可逆性):
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.