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