More PL/I fun (with my Z80)

I received a couple of excellent comments regarding my previous blog posts on PL/I and it’s compiler bug with double precision and the ‘**’ operator. I replaced ‘**’ with a dead simple ‘doexp()’ function that simply did serial multiplications using a loop. It was not very sophisticated, nor very efficient.

Ed suggested I search for “exp_by_squaring_iterative”, which I did. It’s a very simple and elegant recursive method for calculating y to the power x, and was easy to implement in PL/I, which supports recursion. After a quick test to prove ‘I got it right’, I replaced ‘doexp()’ with ‘powsq()’ (my name for it) in both fracture programs as well as the concentration programs.

Tests with the concentration programs proved the new method is almost twice as fast as the brute-force function, which is very rewarding.

The next problem I ended up tackling (and am still working on) turns out to be caused by the ‘weirdness’ of 2D arrays. Basically, different programming languages order arrays differently. C (and PL/I) order 2D arrays by row-column, while FORTRAN orders by column-row, when the array is populated by either BLOCK DATA (FORTRAN) or {} (c) or ‘static input ()’ (PL/I).

Figuring out that the original FORTRAN program loaded the arrays in a completely different manner than PL/I has caused me no little headache. I ended up having to debug both the FORTRAN code to see how the array was stored as well as the PL/I program.

Still, I’m having fun and still enjoying my foray into PL/I.

Once again I broke a compiler…

Back when I was writing FORTRAN ‘for real’ (a.k.a. in a production environment), I managed to find a bug in the FORTRAN compiler that was confirmed and verified independently by the compiler creator and supplier.

Not that I was too happy about it as the bug was totally reproducible and quite severe. It was also just obscure enough that it was never fixed. We worked around it and then went on to other things.

Well, I’ve found a bug in another compiler. This one dates from the same time frame, but is the Digital Research PL/I compiler I’ve been playing with on my Z80 single board.

Now, disclaimer: this ‘bug’ may well be a known and documented condition, but it’s not in the DR written PL/I compiler manual, and any other documentation has probably been lost over the ages.

So with that, I mentioned in my last post that I had to build my own ‘doexp()’ subroutine for the concentration program because squaring a negative number was failing ‘Error(3)’.

Well, it happened again. This time I was converting an old fracture program from FORTRAN and it was failing with OVERFLOW(1) errors. After some serious tracing with debug prints, I found it was again the ‘**’ exponent function that was the cause. Looking at the numbers coming from the program, there was NO WAY it could be a real calculation problem (-.0152534 ** 2 is NOT an overflow!!!) so it had to be the ‘**’ again.

To verify I grabbed the ‘doexp()’ subrouting from the concentration program and popped into the fracture program, and sure enough it runs.

As there is no way I can examine the source of the built-in function, I’ll just have to use my ‘doexp()’ from now on.

At least the program runs now. 🙂