-1

I'm trying to translate a fortran program to a c++ version, and then I found such code:

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

And END is the end.

My c++ verison is:

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;
            }
        }
    }
}

I'm sure that it is wrong, but could not figure out the correct one. So how to translate the fortran code to c++?

Alexander Vogt
  • 17,879
  • 13
  • 52
  • 68

1 Answers1

1

The most important thing is to understand what the code does.

This looks like a nasty piece of code, but on closer analysis, it is clear what it does - it divides the values of iu by i, i ranging from 2 to 7, for as long as all values are divisible by i.

Some work is wasted by dividing by non-prime numbers.

You should ask yourself why it stops at 7. This could be a hard-coded limit due to small memory sizes a few decades ago.

Here is a version in C (not tested, and the indentation got messed up).

#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;
        } 
    }
    }
}

And here is a version in modern Fortran (to make the algorithm clearer):

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