Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!ukma!nrl-cmf!ames!elroy!mahendo!jplgodo!wlbr!etn-rad!jru
From: jru@etn-rad.UUCP (John Unekis)
Newsgroups: comp.lang.c,comp.sys.ibm.pc
Subject: Re: What's Wrong here?
Message-ID: <312@etn-rad.UUCP>
Date: Mon, 30-Nov-87 19:37:05 EST
Article-I.D.: etn-rad.312
Posted: Mon Nov 30 19:37:05 1987
Date-Received: Thu, 3-Dec-87 23:26:18 EST
References: <278@westmark.UUCP> <6755@brl-smoke.ARPA> <6855@sunybcs.UUCP> <6761@brl-smoke.ARPA>
Reply-To: jru@etn-rad.UUCP (John Unekis)
Organization: Eaton Inc. IMSD, Westlake Village, CA
Lines: 31
Xref: mnetor comp.lang.c:5656 comp.sys.ibm.pc:10639

In article <6761@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) writes:
>In article <6855@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>>In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) writes:
>>That is, when the sign bit is turned on as
>>a result of bit shifting, it can not be turned off again,......
>Is this REALLY true of the 80*86 family?  If so, it's the only
>architecture I've ever heard of that behaves this way......
No, It is not true. I think Doug was confused by the difference between a
logical shift instruction, and an arithmetic shift. With either type of 
shift, a left shift places the next-to-most-significant bit into the 
most-signifacant-bit , whether it is a one or a zero. When you perform a 
right shift however, the logical shift moves everything down one bit and
turns off(makes zero) the high bit. The arithmetic shift moves everything
down one bit and leaves the high bit set to its previous value(whether one
or zero). Since the high bit is the sign bit, this leaves a negative number
negative after the shift. Microsoft C uses the arithmetic shift whenever 
you do a >> shift in C. This is nice in a way, because a right shift by 
one bit is always equal to a divide by two. That is 4 >> 1 = 2, and 
-4 >> 1 = -2.  It does however lead to some frustration if you are using 
shift operations to isolate something like bit flags. If you take a 16bit
integer and put the value 32767 in it, you get 0111111111111111 in binary,
a left shift gives you 1111111111111110, which is a -2, If you follow with
a right shift, you get 1111111111111111, which is a -1. So a right shift
is not always the inverse of a left shift in Microsoft C. If it is important
to you not to propagate the sign bit , I suggest you follow a right shift
with an and operation such as result = (value >> n) & (32767 >> (n-1)). It
is a horrible kludge, but it may be easier than coding an assembler routine
to perform a logical right shift instead of the arithmetic right shift.

I am not particularly fond of intel 80?86 hardware, but they are not 
THAT bad.