当我们使用基数2(二进制)来计算每个位时,都有不同的正值(符号位除外),例如:

 0   0   0  0  0  0  0
64  32  16  8  4  2  1

现在我需要在-120 - 120范围内使用3的有符号幂进行计数,我的“位”是:
  0     0    0    0    0   0   0   0    0    0
-81   -27   -9   -3   -1   1   3   9   27   81

除了记住什么组合会导致程序开始时的哪个值之外,我应该如何找到一个使用这些位进行实际计数的方法?
用更数学的术语来说,给定一个数,我应该如何找到“3位幂”的组合,它等于。
作为解决这个问题的另一种方法,与其直接在这些编号格式之间进行转换,还不如假设n已经转换成这种“3次方”格式,我可以直接在这种格式中找到n(不需要转换回十进制,加1再转换回十进制)。然而,我也不知道如何朝这个方向前进。
由于主项目是其核心,是一个更高级的文件转换器,这是我需要支持的文件类型之一,所以我只能使用这种表示数字的方法。
如果这是错误的论坛,请告诉我正确的论坛我不确定这种问题到底应该问在哪里。
编辑:n的表示形式是不设置任何位,我相信所有的位都是,只要设置了其中一个位,它的值就会加到数字上。

最佳答案

这是塞顿计算机中使用的balanced ternary system。每个“数字”(-1,0,1)被称为trit类似于位。
在没有硬件支持的情况下,您可以在这个系统中使用迭代来转换数字-获得三(p)参与给定值的最大功率,用当前符号填充相应的trit,从值中减去p,调整符号并继续。
注意MST=1(最显著的trit)包含在(3^n-3^(n-1)-...-1)(3^n+3^(n-1)+...+1)之间的值中例如,2-nd trit(9)是从5到13的值中最早的集合1。括号中的值是几何级数的和,并且存在短公式。
所以我们可以从第0个trit移到更重要的trit,重新计算极限工作Delphi代码,检查-40..40限制

 function ToBTS(Value: Integer): TArray<Integer>;
  var
    p, sgn, t: Integer;

    procedure AdjustSign();
    begin
      if value < 0 then begin
         sgn := -sgn;
         value := -value;
      end;
    end;

  begin
   SetLength(Result, 8);
   for t := 0 to 7 do
     Result[t] := 0;
   sgn := 1;
   p := 1; // power of three
   t := 0; // trit number

   AdjustSign();
   while p * 3 - 1 < 2 * value do begin //forward traversal
     p := p * 3;
     t := t + 1; //move to more significant trit
    end;

   while value <> 0 do begin
      Result[t] := sgn;
      value := value - p;
      AdjustSign();
     //backward traversal
      while (value > 0) and (p - 1 >= 2 * value) do begin
        p := p div 3;
        t := t - 1; //move to less significant trit
      end;
    end;
 end;

输出(+for 1,-for-1)
-13 0---
-12 0--0
-11 0--+
-10 0-0-
-9 0-00
-8 0-0+
-7 0-+-
-6 0-+0
-5 0-++
-4 00--
-3 00-0
-2 00-+
-1 000-
0 0000
1 000+
2 00+-
3 00+0
4 00++
5 0+--
6 0+-0
7 0+-+
8 0+0-
9 0+00
10 0+0+
11 0++-
12 0++0
13 0+++

关于algorithm - 用3的幂进行计数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48377083/

10-14 20:54