spigot算法的错误答案

时间:2019-04-05 21:52:30

标签: ada pi spigot-algorithm

我正在编码用于在ada中显示pi的数字的自锁算法,但我的输出是错误的,我不知道为什么

我尝试弄乱循环范围和输出数据的不同方法,但没有任何效果

with ada.integer_text_io; use ada.integer_text_io;
with Ada.Text_IO; use Ada.Text_IO;

procedure Spigot is
    n : constant Integer := 1000;
    length : constant Integer := 10*n/3+1;
    x,q,nines,predigit :Integer :=0;
    a: array (0..length) of Integer;

begin
    nines:=0;
    predigit:=0;

    for j in 0..length loop
        a(j):=2;
    end loop;

    for j in  1..n loop
        q:=0;
        for i in reverse 1..length loop
            x:=10*a(i) + q*i;
            a(i):= x mod (2*i-1);
            q:= x/(2*i-1);
        end loop;

        a(1):= q mod 10;
        q:=q/10;

        if q = 9 then
            nines:=nines+1;
        elsif q = 10 then
            put(predigit+1);
            for k in 0..nines loop
                put("0");
            end loop;
            predigit:=0;
            nines:=0;
        else
            put(predigit);
            predigit:=q;
            if nines/=0 then
                for k in 0..nines loop
                    put("9");
                end loop;
                nines:=0;
            end if;      
        end if;   
    end loop;
    put(predigit);
end Spigot;

所以它应该只显示在0 3 1 4 1 5 9 2 6 5 3 5 8 9 ...但是我得到的输出是0 3 1 4 1 599 2 6 5 3 5 89 ...它应该一次只能是1位数,而且pi的输出值也不完全正确

2 个答案:

答案 0 :(得分:2)

我认为您正在翻译this answer

您需要更加小心索引和循环范围;例如,您已经翻译

for(int i = len; i > 0; --i) {
  int x  = 10 * A[i-1] + q*i;
  A[i-1] = x % (2*i - 1);
  q = x / (2*i - 1);
}

for i in reverse 1..length loop
    x:=10*a(i) + q*i;
    a(i):= x mod (2*i-1);
    q:= x/(2*i-1);
end loop;

循环范围是相同的。但是在第二行中,C代码使用A[i-1],而您的代码使用a(i);在第三行中也是如此。

稍后,

  for (int k = 0; k < nines; ++k) {
    printf("%d", 0);
  }

你有

  for k in 0..nines loop
      put("0");
  end loop;

,其中C循环从0nines - 1,但是您的循环从0nines。因此,您多花了0个字符(后来,9也多了)。

此外,您应该使用put (predigit, width=> 0)

答案 1 :(得分:2)

我对算法不太了解,无法讨论为什么数字不正确,但是我确实注意到了一些问题:

  1. 您的数组定义为边界0 ..长度,这将为您增加1个元素
  2. 在进行计算的循环中,从1..length循环,这是可以的,但您并没有始终如一地调整变量i。数组索引必须比实际计算中使用的i小1(请记住,它们仍然必须正确地位于数组的边界内)。例如

    $rows = getDataFromDatabase();
    foreach($rows as $row){
      echo "
        <div class='tbook' align='center'>
          <div class='tr'>
           <div class=''>$row['name']</div>
           <div class=''>$row['role']</div>
           <div class=''>$row['admin']</div>
          </div>
        </div>
      "
    }
    

    需要是

        x:=10*a(i) + q*i;
    

        x:=10*a(i-1) + q*i;
    

    取决于您决定数组边界的范围。这适用于代码中的多行。看到这个Stackoverflow thread

  3. 当数组从0开始时分配A(1)

  4. 要打印出“ 0”和“ 9”的循环应为1..length或0 ..length-1
  5. 使用Integer_Text_IO.Put打印数字时,需要指定宽度1以消除空格

可能还有更多,这就是我所看到的。