【问题标题】:fortran77 do continue loops confusedfortran77 继续循环混淆
【发布时间】:2015-01-24 14:24:57
【问题描述】:

我正在尝试将一个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++呢?

【问题讨论】:

  • 尝试使用 f2c,会拯救你的理智
  • 先画流程图。 f2c 在生成可读代码方面从来都不是特别好,我看不出它如何拯救任何人的理智。
  • 第一个if 语句是arithmetic if...它可能不会像您期望的那样;-)
  • @Cyber​​ 哈哈哈。很有趣。

标签: c++ fortran fortran77 do-loops


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 2011-08-19
    • 2013-09-24
    • 2018-12-16
    相关资源
    最近更新 更多