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.