[comp.lang.c] Bug fix for Turbo C

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (06/30/91)

In article <1991Jun29.190505.10335@nntp-server.caltech.edu>, eychaner@suncub.bbso.caltech.edu (Another casualty of applied metaphysics.) writes:
> short a_250K_array[];				/* The big array */
> int bit_shift,					/* Bit shift */
>     array_size, i;				/* Array size and index */

> for (i = 0; i < arraysize; i++) {
>     a_250K_array[i] >>= bit_shift;
>     /* I shouldn't index the array like this; but it makes the code clearer */
>     }

> What I want is to divide each member of the 250K short array by 2^bit_shift.
> The 250K array contains both positive and negative numbers.

This has been beaten to death in SIGPLAN Notices over the years, but
are you aware that "arithmetic right shift k bits" is _NOT_ the same
thing as "divide by 2**k"?  For example,
	((-1) /  2) == 0,
but	((-1) >> 1) == -1

> In Vax C 3.0 (it's not the greatest, but it's adequate, OK?) section 7.5.7
> SEEMS to guarantee that this works by filling the vacated bits with a copy of
> E1's sign bit (and indeed, from experience, it does work as expected). However,
> someday (dream on) Vax C might become ANSI standard, and I will need to change
> the way I do this.  (Here, portability isn't a big issue, but having a system
> upgrade break code might be.)

ANSI C hasn't changed _anything_.  That, in fact, is your problem.
I was rather irritated too, when I found out that >> sometimes gave you
an unsigned shift when applied to signed numbers.  And in my application
I really did want shifts, not divides.  But the way I found out was by
coming up against a pre-ANSI compiler which did it the other way.

If you're not worried about portability, you may not have a problem.  The
reason for right shifts being sloppy is to let implementors use whatever
is fastest, and that depends on what shifts the machine has.  The easiest
way to say "shift" on a VAX is ASHL, and that does what you want.  Other
compilers are likely to make the same choice.  If portability is not a
big issue, you might consider writing a few lines of assembly code.

-- 
I agree with Jim Giles about many of the deficiencies of present UNIX.

eychaner@suncub.bbso.caltech.edu (Another casualty of applied metaphysics) (07/01/91)

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:
>I (Another casualty of applied metaphysics.) write:
>> short a_250K_array[];				/* The big array */
>> int bit_shift,					/* Bit shift */
>>     array_size, i;				/* Array size and index */
>
>> for (i = 0; i < arraysize; i++) {
>>     a_250K_array[i] >>= bit_shift;
>>     /* I shouldn't index the array like this; but it makes the code clearer */
>>     }
>
>> What I want is to divide each member of the 250K short array by 2^bit_shift.
>> The 250K array contains both positive and negative numbers.
>
>This has been beaten to death in SIGPLAN Notices over the years, but
>are you aware that "arithmetic right shift k bits" is _NOT_ the same
>thing as "divide by 2**k"?  For example,
>	((-1) /  2) == 0,
>but	((-1) >> 1) == -1

Yeah, I know, I know.  So it's not REALLY division by 2^k.  So sue me.  (BTW,
it is division by 2^k for all numbers EXCEPT -1, is it not?)

>If you're not worried about portability, you may not have a problem.

Well, I'm not worried about portability.

-G.
******************************************************************************
Glenn Eychaner - Big Bear Solar Observatory - eychaner@suncub.bbso.caltech.edu
"There is no monopoly of common sense / On either side of the political fence"
                                                            -Sting, "Russians"