如何将两个二进制数合并为一个三进制数
How to merge two binary numbers into a ternary number
我有两个二进制整数,x0
和 x1
,它们是 8 位(因此它们的范围从 0 到 255)。对于这些数字,此陈述始终为真:x0 & x1 == 0
。这是一个例子:
bx0 = 100 # represented as 01100100 in binary
bx1 = 129 # represented as 10000001 in binary
所以我需要对这些数字进行如下操作。首先,将这些二进制表示解释为ternary(base-3)数字,如下:
tx0 = ternary(bx0) # becomes 981 represented as 01100100 in ternary
tx1 = ternary(bx1) # becomes 2188 represented as 10000001 in ternary
然后,将tx1
的三元表示中的所有1
交换为2
:
tx1_swap = swap(tx1) # becomes 4376, represented as 20000002 in ternary
然后对它们使用三元版本的OR
得到最终的组合数:
result = ternary_or(tx0, tx1_swap) # becomes 5357, represented as 21100102 in ternary
我不需要在任何时候保存三元表示,我只需要结果,例如 result=5357
。当然,我可以通过将数字转换为二进制、转换为三进制等来对此进行编码。但我需要此操作快速,因为我在代码中多次执行此操作。在 python 中实现这个的快速方法是什么?
最快的方法可能是小数加法:
a = 1100100
b = 10000001
result = int(str(a+2*b),3) #5357
你不会在 python(或我所知道的任何其他语言)中找到三元运算符。因为你需要超越按位运算,你的下一个最快的选择是整数加法,它地球上的每台计算机都经过优化以完成。
转换为三进制以完成此操作的其他解决方案将要求您来回转换为字符串,这比十进制加法花费的时间长得多。这只需要在最后转换一个字符串,假设您甚至需要最终三元数的十进制版本。
为像我这样的傻瓜重新解释:
"encode" 两个三元二进制互斥数 (w & b == 0
) 的直接方法是:
white_black_empty = lambda w, b: int(format(b, 'b'), base=3) + \
int(format(w, 'b').replace('1','2'), base=3)
以下是所有可能的 2 位变体:
white_black_empty(0b00, 0b00) == 0
white_black_empty(0b00, 0b01) == 1
white_black_empty(0b01, 0b00) == 2
white_black_empty(0b00, 0b10) == 3
white_black_empty(0b00, 0b11) == 4
white_black_empty(0b01, 0b10) == 5
white_black_empty(0b10, 0b00) == 6
white_black_empty(0b10, 0b01) == 7
white_black_empty(0b11, 0b00) == 8
通过观察 int(format(w, 'b').replace('1','2'), base=3)
实际上等于 int(format(w, 'b'), base=3)
的两倍(例如,20220023 == 10110013*2),我们得到@Mark Dickinson 在上面的评论中发布的解决方案:
white_black_empty = lambda w, b: int(format(b, 'b'), base=3) + \
int(format(w, 'b'), base=3)*2
我有两个二进制整数,x0
和 x1
,它们是 8 位(因此它们的范围从 0 到 255)。对于这些数字,此陈述始终为真:x0 & x1 == 0
。这是一个例子:
bx0 = 100 # represented as 01100100 in binary
bx1 = 129 # represented as 10000001 in binary
所以我需要对这些数字进行如下操作。首先,将这些二进制表示解释为ternary(base-3)数字,如下:
tx0 = ternary(bx0) # becomes 981 represented as 01100100 in ternary
tx1 = ternary(bx1) # becomes 2188 represented as 10000001 in ternary
然后,将tx1
的三元表示中的所有1
交换为2
:
tx1_swap = swap(tx1) # becomes 4376, represented as 20000002 in ternary
然后对它们使用三元版本的OR
得到最终的组合数:
result = ternary_or(tx0, tx1_swap) # becomes 5357, represented as 21100102 in ternary
我不需要在任何时候保存三元表示,我只需要结果,例如 result=5357
。当然,我可以通过将数字转换为二进制、转换为三进制等来对此进行编码。但我需要此操作快速,因为我在代码中多次执行此操作。在 python 中实现这个的快速方法是什么?
最快的方法可能是小数加法:
a = 1100100
b = 10000001
result = int(str(a+2*b),3) #5357
你不会在 python(或我所知道的任何其他语言)中找到三元运算符。因为你需要超越按位运算,你的下一个最快的选择是整数加法,它地球上的每台计算机都经过优化以完成。
转换为三进制以完成此操作的其他解决方案将要求您来回转换为字符串,这比十进制加法花费的时间长得多。这只需要在最后转换一个字符串,假设您甚至需要最终三元数的十进制版本。
为像我这样的傻瓜重新解释:
"encode" 两个三元二进制互斥数 (w & b == 0
) 的直接方法是:
white_black_empty = lambda w, b: int(format(b, 'b'), base=3) + \
int(format(w, 'b').replace('1','2'), base=3)
以下是所有可能的 2 位变体:
white_black_empty(0b00, 0b00) == 0
white_black_empty(0b00, 0b01) == 1
white_black_empty(0b01, 0b00) == 2
white_black_empty(0b00, 0b10) == 3
white_black_empty(0b00, 0b11) == 4
white_black_empty(0b01, 0b10) == 5
white_black_empty(0b10, 0b00) == 6
white_black_empty(0b10, 0b01) == 7
white_black_empty(0b11, 0b00) == 8
通过观察 int(format(w, 'b').replace('1','2'), base=3)
实际上等于 int(format(w, 'b'), base=3)
的两倍(例如,20220023 == 10110013*2),我们得到@Mark Dickinson 在上面的评论中发布的解决方案:
white_black_empty = lambda w, b: int(format(b, 'b'), base=3) + \
int(format(w, 'b'), base=3)*2