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