Path: utzoo!utgpu!watmath!clyde!att!pacbell!ames!amdahl!uunet!portal!cup.portal.com!dan-hankins
From: dan-hankins@cup.portal.com (Daniel B Hankins)
Newsgroups: comp.sys.amiga.tech
Subject: Re: Dividing by a power of two (Re: Aztec compiler ineffecienci
Message-ID: <12046@cup.portal.com>
Date: 3 Dec 88 04:48:56 GMT
References: <8811292001.AA02370@postgres.Berkeley.EDU>
Organization: The Portal System (TM)
Lines: 52


     In article <8811292001.AA02370@postgres.Berkeley.EDU>,
dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) makes some more comments about
the value of tricks such as shifting to divide by powers of two.

     I'm afraid I'm going to have to disagree with you on this one, Matt. 
Very recently, I spent a miserable week trying to find a bug caused by
exactly this kind of programming.

     I was assigned the task of updating a very large (18000+ lines) piece
of PL/I code (not actually PL/I, but similar enough so that you get the
idea).  One of the data structures in the program was a large array of
buffers.  The previous programmer had not bothered to declare a constant,
but rather had assumed that the buffer size would never change.  Of course,
on of my tasks was to enhance the program to handle data larger than the
current buffer size.

     So I went merrily through the program files, searching for every
instance of the number '150', and all the derivatives thereof I could
imagine.  One was tricky to find - to format the buffer for output he
divided it up into five segments.  Each segment had its own line of code in
the program with the beginning and ending addresses hard-coded (such as
BUFFER(31:50).  Well, I thought I got them all.

     Then one day I got a call from an irate user complaining that the
output data was completely out of whack.  Then started the hunt for a week.
At the end of the week, I found the problem, almost by accident.

     The previous programmer had padded each buffer with flags and other
data to make the addresses of the buffers separate by 256.  Sometimes he
needed the index of a buffer he had the address of.  So what he would do is
to subtract the address of BUFFER(0) from the address of the buffer in
question.  He then stored this difference in a two-byte field that had
two one-byte subfields.  He would then read back the high-order byte, thus
implicitly dividing by 256 (much like the bit-shift technique).

     When I rewrote the code, the buffer size itself increased to 256
bytes.  Each buffer plus the flags was somewhat more than this.  Therefore
the addresses of the buffers were separated by more than 256 bytes, and
each time his code attempted to compute the index of a buffer, it would get
values that were too high for any buffer above BUFFER(5).

     The moral of the story is:  Unless no one else will ever have to read
or maintain your program, DON'T DO THIS!  *Parameterize*.  Let the compiler
optimize it if the constant is a power of two.

     The only case I can think of where this might be okay is if one wishes
to divide an integer by a power of two (an equation like y = x / (2 ** z)).
Even then I would hesitate.


Dan Hankins