Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Forever loop with index counter

WSinc
New Contributor I
1,895 Views

I realize you can have a forever loop as follows:

 

DO

Code etc.

ENDDO

But is there a way to do that with an index counter?

For example, I might want to loop with an index K thru

all positive possible values of K, if its an integer(4).

The only way I am using it now, is to put a very high number on the upper limit as follows:

KHIGH=2**31-1

Do K=1,KHIGH

code, etc.

enddo

The upper limit here is the high value for a 32 bit integer.

any ideas?

0 Kudos
20 Replies
WSinc
New Contributor I
1,879 Views

You can also do that as follows:

K=0

do

k=k+1

CODE, etc.

enddo

 

But I was looking for a "clean" way to do this - - -

0 Kudos
Steven_L_Intel1
Employee
1,879 Views

HUGE(0) returns the largest positive value for default integer. You could write:

DO K=1,HUGE(K)

and always have the right kind.

0 Kudos
WSinc
New Contributor I
1,879 Views

Oh, yeah - I forgot about the HUGE() thing -

Thanks ! ! !

0 Kudos
Steven_L_Intel1
Employee
1,879 Views

You might want to be careful, though - sometimes when you get loop limits near the boundaries of an integer kind, the loop-ending test doesn't work right. For example, if K gets incremented past HUGE, it will wrap around to a negative number and the loop won't end. Doing your own increment might work better, depending on what you are really trying to do.

0 Kudos
WSinc
New Contributor I
1,879 Views

I did some experimentation -

You're right, I have to say something like:

DO K=1, HUGE(K)-10

CODE, ETC.

ENDDO

Also, apparently the compiler does not allow me to (properly) use a DO LOOP

where K is integer(8). Well, it doesn't complain, but the results appear to be unpredictable.

Wouldn't a warning be appropriate?

Not that it would be particularly useful to do that, unless I somehow HAD to have an 8 byte variable.

 

0 Kudos
Steven_L_Intel1
Employee
1,879 Views

Please show an example of "the compiler does not allow me to (properly) use a DO LOOP where K is integer(8)." This is supported.

0 Kudos
WSinc
New Contributor I
1,879 Views

OK,= here is one that doesn't work:

integer(8) k,dk
data  dk/2000000000/


    do k=1,huge(k),dk
        print *,"k=",k
    enddo
    read(*,*)

!  k=1,huge(k),1000000000 does work

!   try making the literal > 2**31
end

 

Interestingly enough, if I make the increment DK a LITERAL, and smaller than 2**31 it

does the DO LOOP properly.

0 Kudos
WSinc
New Contributor I
1,879 Views

Apparently the problem comes from making the increment DK something besides a literal.

Here is an enhanced version:

integer(8) k,dk8
integer dk4
    data dk8/2000000/
    data dk4/2000000/
    do k=1,huge(k),dk4
        print *,"k=",k
    enddo
    read(*,*)
end

Whether I use DK4 or DK8, it still does not execute the DO loop properly.

I never get a print statement output.

But it seems to work if I use a literal instead.

0 Kudos
WSinc
New Contributor I
1,879 Views

I did a little more experimenting - none of these increments work.

I tried using the debugger to step thru it, it skips the DO LOOP entirely - -

In all cases.

    integer(8) k,dk8/3000000000/
    integer dk4/1000000/
    integer(2) dk2/20000/
    integer(1) dk1/100/
    do k=1,huge(k),dk1
        print *,"k=",k
    enddo
    read(*,*)
    end

0 Kudos
Steven_L_Intel1
Employee
1,879 Views

As I mentioned earlier, when you have a loop that has limits near the boundaries of the kind, you may run into trouble. The computation of the loop count might overflow, which is probably what is happening in this case. I recommend not doing a 1,huge(k) type loop, you will probably not get what you want. I do have a bit of a hard time believing that's really what your program requires.

0 Kudos
WSinc
New Contributor I
1,879 Views

Well, I can decrease the upper limit if I need to -

I had an application where I wanted to go thru a randomized count of all possible integers.

However, I still don't understand why it would not execute the DO LOOP at least once.

Are you saying that it computes the number of times it executes it ahead of time,

rather than doing a comparison after each iteration?

Also,  why the problem goes away when I use a literal instead.

I say this, because a SIMULATED do loop works fine. Example:

Integer(8)  K,DK/1000000000000/

K=1

10  k=k+dk

print *,"k=",k

if(k < huge(k)-dk ) go to 10

0 Kudos
IanH
Honored Contributor III
1,879 Views

billsincl wrote:

In all cases.

    integer(8) k,dk8/3000000000/
...

I have no idea how the data-statement-like-initialization extension works, but note the constant in between the slashes is default integer - and the value of that constant is too big to fit into default integer.

0 Kudos
Steven_L_Intel1
Employee
1,879 Views

The compiler sometimes computes the count in advance, sometimes tests the DO variable. It depends on what you do in the loop and what it thinks is best. The standard model of a counted DO loop is to compute the count in advance.

0 Kudos
WSinc
New Contributor I
1,879 Views

The upper limit for Integer(8) is 9.22 x 10**18 roughly, so you can have 19 digits in the literal.

Try this:

!                1234567890123456789

integer k8/9220000000000000000/

print *,k8

plus or minus 2**63 roughly are the limits (?)

As far as the DO LOOP, I tested it for Integer(1) and integer(2), and the upper limit problem does not appear there.

So it appears that something is going wrong when they do the integer(4) and integer(8) arithmetic to count loop iterations.

I guess one should "play it safe" and SIMULATE the DO LOOP instead.

Not much arithmetic burden incurred - - -

0 Kudos
WSinc
New Contributor I
1,879 Views

Something else kinda weird - - 

This loop DOES work ! ! 

integer (4) dk4,k4,khi4   

   dk4=1000000

    khi4=huge(k4)
    do k4=dk4,khi4,dk4
        print *,"k4=",k4
    enddo

0 Kudos
andrew_4619
Honored Contributor III
1,878 Views
    integer(8) k1,k2,dk,k3
    data  dk/2000000000_8/

    k3=1
    10 continue    
    k2=huge(k1)-k3
    do k1=1_8,k2,dk
        print *,"k1=",k1,k3
    enddo
    k3=k3+1_8
    goto 10

So under debug I but a break at the print. the first hit (after a bit of a wait for a sqillion loops) is when k3=1999999999 ie dk-1. This would be because it is doing some sums on the loop counters looking at what the last loop  iteration might be and overflowing. That is probably a compiler bug as k2 is a long way off huge in this instant.

 

0 Kudos
WSinc
New Contributor I
1,878 Views

Very good app4619  ! ! !

Now try making the upper limit about HALF was it was before.

I found out that the problem goes away.

See what you get.....

0 Kudos
andrew_4619
Honored Contributor III
1,878 Views

Don't need to test further, it will fail when k2+dk>=huge

 

0 Kudos
WSinc
New Contributor I
1,878 Views

Even when the upper limit is significantly smaller than HUGE, it still fails-

Take a look at this code fragment.

! everything is Integer(4) 

khi4=huge(k4)

dk4=100000000
15  print *,"do loop: khi4=",khi4
    print *,"kount=",(khi4-1)/dk4+1
    do k4=1,khi4,dk4
        print *,"k4=",k4
    enddo
    read(*,*)
    khi4=khi4*0.99
    go to 15
    read(*,*)

In the above example, it does the iteration on K4HI quite a few times before it finally works.

I am using the correct formula for the number of counts in the DO LOOP, and I get 22 (the first time).

The DO LOOP does not execute properly until quite a bit after kount = 21.

so, whatever arithmetic they are using to get the KOUNT value, it apparently is incorrect.

BUT - - If I say instead DK4, K4HI, DK4 it is correct every time  ! ! !

0 Kudos
WSinc
New Contributor I
1,802 Views

Hi again -

I revised that code fragment.

It turns out that if the lower limit is < DK4 it does not execute the DO LOOP properly.

I set the breakpoint inside the DO LOOP to see when it will execute it.

The upper limit can be = HUGE(K4) - -  it will still work.

    khi4=huge(k4)
    klo4=1
    dk4=1000000
15  print *,"do loop: klo,hi=",klo4,khi4
    print *,"kount=",(khi4-klo4)/dk4+1
    do k4=klo4,khi4,dk4
        print *,"k4=",k4
    enddo
!    read(*,*)
!    khi4=khi4*0.99
    klo4=klo4+1
    go to 15

I have not tried this with INTEGER(8) variables, but I suspect I will get the same thing.

0 Kudos
Reply