# Forth double loops

Given a double number D on the stack, what's a reasonable way of looping D times? I recently needed to do this to support file reading on a 16-bit Forth.

Clearly you can just make a loop by counting down:

```begin
<something>
-1. d+ 2dup d0=
until
2drop
```

But there is a more elegant arrangement using a nested pair of DO..LOOPs.

The inspiration is this ancient Z80 technique of using two 8-bit loops to form a 16-bit counter: http://map.grauw.nl/articles/fast_loops.php

The Forth equivalent looks quite

```: prep over 0<> - ;

...
prep 0 do
0 do
<whatever>
loop 0
loop drop
```

prep adjusts the loop counter, incrementing the high count only if the low count is nonzero.

So for example a loop count of \$123456 would be represented on the stack as:

```\$3456 \$12
```

prep adjusts the high count to \$13:

```\$3456 \$13
```

So the outer DO..LOOP executes \$13 times. The first inner do executes \$3456 times. The subsequent iterations are all performing:

```0 0 DO .. LOOP
```

and hence execute \$10000 times.

This works well, but there does not seem to be an easy way of computing the double counter value.

There is a small further optimization possible. Instead of adjusting the outer loop counter, prep can compute compute a DO..LOOP starting value of either 0 or -1:

```: prep over 0<> ;

...
prep do
0 do
<whatever>
loop 0
loop drop
```