我的CPU寄存器包含二进制整数0101
,等于十进制数5:
0101(4 + 1 = 5)
我希望寄存器包含等于十进制10的二进制整数,就好像原始二进制数0101是三元组(基数3)并且每个数字恰好是0或1:
0101(9 + 1 = 10)
我如何在现代CPU或GPU上执行此操作,1。内存读取最少,2。最少的硬件指令?
答案 0 :(得分:2)
使用累加器。 C-ish Pseudocode:
var accumulator = 0
foreach digit in string
accumulator = accumulator * 3 + (digit - '0')
return accumulator
要加快乘以3,你可以使用((accumulator<< 1)+ accumulator),但是一个好的编译器可以为你做到这一点。
如果您的数字的很大一部分在相对较小的范围内,您还可以预生成查找表以立即从base2转换为base3(使用base2值作为索引)。您还可以使用查找表来加速前N个数字的查找,因此您只需为剩余数字的转换付费。
答案 1 :(得分:-1)
这个C程序会这样做:
#include <stdio.h>
main()
{
int binary = 5000; //Example
int ternary = 0;
int po3 = 1;
do
{
ternary += (binary & 1) * po3;
po3 *= 3;
}
while (binary >>= 1 != 0);
printf("%d\n",ternary);
}
循环在我的32位Intel机器上编译成这个机器代码:
do
{
ternary += (binary & 1) * po3;
0041BB33 mov eax,dword ptr [binary]
0041BB36 and eax,1
0041BB39 imul eax,dword ptr [po3]
0041BB3D add eax,dword ptr [ternary]
0041BB40 mov dword ptr [ternary],eax
po3 *= 3;
0041BB43 mov eax,dword ptr [po3]
0041BB46 imul eax,eax,3
0041BB49 mov dword ptr [po3],eax
}
while (binary >>= 1 != 0);
0041BB4C mov eax,dword ptr [binary]
0041BB4F sar eax,1
0041BB51 mov dword ptr [binary],eax
0041BB54 jne main+33h (41BB33h)
对于示例值(十进制5000 =二进制1001110001000),它产生的三元值是559899.