-1

我正在尝试将 fortran 程序翻译成 c++ 版本,然后我发现了这样的代码:

100 DO 120 I=2,7
    DO 110 J=1,3
    IF(IU(J)/I*I-IU(J))120,110,120
110 CONTINUE
    GO TO 130
120 CONTINUE
    GO TO 150
130 DO 140 J=1,3
140 IU(J)=IU(J)/I
    GO TO 100
150 CONTINUE
    END

并且END是结束。

我的 C++ 版本是:

bool flag=true;

while(flag){
    flag=false;
    for (int i = 2; i <= 7; i++) {
        for (int j = 0; j < 3; j++) {
            if ((IU[j]/i*i==IU[j])) {
                flag=true; break;
            }
            else {
                continue;
            }
        }
        if (!flag) {
            break;
        }
        else {
            for (int j = 0; j < 3; j++) {
                IU[j]=IU[j]/i;
            }
        }
    }
}

我确定这是错误的,但无法找出正确的。那么如何将fortran代码翻译成c++呢?

4

1 回答 1

1

最重要的是了解代码的作用。

这看起来像是一段令人讨厌的代码,但仔细分析后,它的作用就很清楚了——它将 iu 的值除以 i,i 的范围从 2 到 7,只要所有值都可以被 i 整除。

除以非素数会浪费一些工作。

您应该问自己为什么它会在 7 处停止。由于几十年前的小内存大小,这可能是硬编码的限制。

这是 C 中的一个版本(未经测试,缩进搞砸了)。

#define NIU 3
#define NDIVISORS 4

void foo(int *iu)
{
  int i,j;

  static int divisors[NDIVISORS] = {2, 3, 5, 7};

  for (i=0; i<NDIVISORS;i++)
    {
      int has_divisor = 1;
      while (has_divisor)
    {
      for (j=0; j<NIU; j++)
        {
          if (iu[j] % divisors[i] != 0)
        {
          has_divisor = 0;
          break;
        }
        }
      if (has_divisor)
        {
          for (j=0; j<NIU; j++)
        iu[j] = iu[j] / i;
        } 
    }
    }
}

这是现代 Fortran 的一个版本(使算法更清晰):

subroutine foo(iu)
  implicit none
  integer, dimension(3), intent(inout) :: iu
  integer, dimension(4), parameter :: divisors =  [2, 3, 5, 7]
  integer :: i

  do i=1, size(divisors)
     do while (all(mod(iu, divisors(i)) == 0))
        iu = iu / divisors(i)
     end do
  end do
end subroutine foo
于 2015-01-25T10:11:20.620 回答