Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!husc6!cmcl2!nrl-cmf!ames!sunybcs!ugfailau
From: ugfailau@sunybcs.uucp (Fai Lau)
Newsgroups: comp.lang.c,comp.sys.ibm.pc
Subject: Re: What's Wrong here?
Message-ID: <6855@sunybcs.UUCP>
Date: Sun, 29-Nov-87 08:21:31 EST
Article-I.D.: sunybcs.6855
Posted: Sun Nov 29 08:21:31 1987
Date-Received: Tue, 1-Dec-87 06:02:38 EST
References: <278@westmark.UUCP> <6755@brl-smoke.ARPA>
Sender: nobody@sunybcs.UUCP
Reply-To: ugfailau@joey.UUCP (Fai Lau)
Organization: SUNY/Buffalo Computer Science
Lines: 55
Xref: mnetor comp.lang.c:5632 comp.sys.ibm.pc:10600

In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) writes:
>In article <278@westmark.UUCP> dave@westmark.UUCP (Dave Levenson) writes:
>>	long n;
>>	n = (1 << 31) -1;
>
>Try changing the first "1" to "1L"; otherwise the whole expression
>is evaluated using (int)s, not (long)s, before the value is assigned.
>If (int) has 16 bits, the left-shift overflows and a variety of
>results are possible, including the one you reported.
>
	The left most bit of both long words of UNIX and Rel 3.0
are sign bits. The same is true for the integer of Rel 4.0.
When you "overshift" a word or integer, the sign bit can only
be shifted "on". That is, when the sign bit is turned on as
a result of bit shifting, it can not be turned off again,
unlike the other bits which represent the value of the
number. So, when you over shift a word of any length,
you'll always get a 1 on the left most bit, except in the
case where the word itself is 0 (ie. has no "on" bit).
	In the above case, a 16 bit word is overshifted.
What's left is a word with *only* the left most bit, the sign
bit, turned on. This bit pattern represents an integer
value of -65536 (I don't want to go into how the *value*
of a negative number is represented). When you put - 1 on it,
overthrow occurs, as the number -65536 is the smallest
integer a 16 bit word can represent. Therefore, instead
of -65537, you get a positive integer of 65535, with
every bit of the word turned on except the sign bit.
Incidently, this value is the maximum that can be
stored in the 16 bit word. Notice that every value
bit is used up. This value is then stored in the long word n.
That is why you got the value you did when you print n.
As a matter of fact, the supposedly correct value
you get from UNIX and Rel 3.0 is a result from
negative overflowing too. This value is the maximum
positive number that can be stored in the 32 bit long
words of UNIX and Rel 3.0.

>By the way, you're treading on thin ice anyway, since (1L << 31) is
>the most-negative 2's complement integer, so subtracting 1 from it
>is yet another undefined operation.  I'm not sure what this code is
>trying to accomplish, but consider using
>	unsigned long n;
>	n = ((unsigned long)1 << 31) - 1;

	The operation is not undefine. By observing the result,
we can 1) identify the scheme with which the system store negative
numbers, 2) what length of word is used as default for operation
like <<. Using much larger number in place of 31 doesn't hurt.
(not original intent, of course)

Fai  Lau
SUNY at Buffalo (The Arctic Wonderland)
UUCP: ..{mit-ems|watmath|rocksanne}!sunybcs!ugfailau
BI: ugfailau@sunybcs