- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 - - -
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HUGE(0) returns the largest positive value for default integer. You could write:
DO K=1,HUGE(K)
and always have the right kind.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh, yeah - I forgot about the HUGE() thing -
Thanks ! ! !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 - - -
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Don't need to test further, it will fail when k2+dk>=huge
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ! ! !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page