如何将二进制整数解释为三元(基数为3)?

时间:2012-02-25 07:36:55

标签: math binary numbers bit-manipulation

我的CPU寄存器包含二进制整数0101,等于十进制数5:

0101(4 + 1 = 5)

我希望寄存器包含等于十进制10的二进制整数,就好像原始二进制数0101是三元组(基数3)并且每个数字恰好是0或1:

0101(9 + 1 = 10)

我如何在现代CPU或GPU上执行此操作,1。内存读取最少,2。最少的硬件指令?

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.

相关问题