Something IBM did right (RT division of negatives).

Stan Switzer sjs at jcricket.ctt.bellcore.com
Wed Nov 9 04:21:30 AEST 1988


In article <973 at goofy.megatest.UUCP> djones at megatest.UUCP (Dave Jones) writes:
> From article <11529 at bellcore.bellcore.com>, by sjs at jcricket.ctt.bellcore.com (Stan Switzer):
> > Anyone wishing to take up the other side of the argument must find an
> > example of an actual situation where having -1/2 yield -1 is useful.
> > (The example must yield cases where the quotient can be both positive
> > or negative, otherwise I can just add or subtract one to the result
> > and get the same effect).
> While I don't want to concede that the way you have restricted debate
> on this is justified, but I'll bite anyway.  I'll use the second 
> example you gave immediately after the challenge.

Actually, the terms are fair enough.  I only ask for demonstration
that the behavior is useful.  Unfortunately I botched my original
posting.  I typed -1 when I meant 0 and 0 when I meant -1.  Just goes
to show that this business can be tricky.  I'm sure you'll find the
terms of debate reasonable now that we agree :-).

> > 2) Bit extraction:  To get the n'th bit from the current (char) pointer
> > "p" (0 bit is low) use "bit = (p[i/BITSPERCHAR]>>(i%BITSPERCHAR)) & 1"
> In the scheme of things you propose, bit[-1] has the same location
> as bit[7].  Is that what you want?  Change the meaning of (-1)/BITSPERCHR
> to be -1, and every bit gets its own happy home.
> Good enough?

Better than good enough.  It's my point exatly.  Too bad the errors in
my first article confused the issue.

Regarding another followup that there are at least three "reasonable"
definitionions of "/" and "%" and that Common Lisp has all three (and
various kitchen appliances :-), whether the other interpretations are
reasonable or not is debatable.  I still have NEVER seen a case where
the other definitions are USEFUL.  Again, too bad the errors in my
original article tend to confuse the issue.

Back to "C".  Given that C does not (fully) define the behavior of
neg/pos or neg%pos, the implementor is free to choose a definition
which allows the shift optimization (the interpretation where -1 / 2
== -1 and -1 % 2 == 1 -- I got it right this time, right?).
Unfortunately, if there is a hardware div/rem instruction the
implementor's best choice is probably to just use the instruction and
let the result be whatever the instruction gives, and since div/rem
instruction is designed with FORTRAN in mind -- FORTRAN requires (last
time I checked) -1/2 to be 0 and mod(-1,2) to be -1 -- the shift
optimization is precluded.

But, as the RT plainly shows, having -1/2 == -1 breaks no code and,
God only knows, probably fixes some code that was broken all along
This is because unless you specifically exploit the discontinuity at
zero in the FORTRAN definition, the behavior is entirely useless.  I
find it difficult that anyone would do that on purpose.

Conclusions:

If you have to do div in software, you might as well design it so that
you can use shifts to handle divides by powers of two.  If you design
hardware, you really ought to consider designing your div instruction
that way as well.  If you have to worry about FORTRAN you might
consider whether it is worthwhile having two flavors of div/rem
instructions.  To be sure, you might look at it and decide not to
bother, but you probably ought to see if it is worthwhile.

It IS a strange idea though, designing an instruction so that it can
sometimes NOT be used -- you have to take into account how much faster
things go when you get to use shift instead.

Stan Switzer  sjs at ctt.bellcore.com



More information about the Comp.lang.c mailing list