delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/07/11/12:45:59

From: Kevin Ashley <k DOT ashley AT ulcc DOT ac DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Infinite loop???
Date: Fri, 10 Jul 1998 17:56:26 +0100
Organization: Posted via ULCC Internet Services
Lines: 50
Message-ID: <35A647BA.41C6@ulcc.ac.uk>
References: <35A3D8C3 DOT 208E6D23 AT cyberdude DOT com>
NNTP-Posting-Host: silver.ulcc.ac.uk
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

dns AT cyberdude DOT com wrote:
> 
> I use the following code:
> unsigned short s=1;
> unsigned int   t=1;
> while ((s<<t)!=0) {     // this loop is infinite! but why?
>       t++; }
> In RHIDE I tried to step trough the code but even when the expression
> seems to be false it stays in the loop.
> changing the loop to:
> while ((unsigned short)(s<<t)!=0) {
>       t++; }            // this gives good answer
> but then the above wont work on data types int/long only if I change !=0
> to != 1
> I don't understand why its working like this. I used BC before and it
> gave me correct answers.

András Sólyom has already pointed you in the right direcction
for understanding the difference. There are two problems with
your assumptions:
(1) ANSI allows left-shift to be arithmetic or logical. At the lowest level,
this means that either 0 bits or 1 bits can be shifted in at the bottom end
if the source was negative.
(2) The value of n << k, where 'n' is an int (of any flavour) and 'k' the
number of bits in that int, is undefined by ANSI. This means the compiler
can generate code that produces any answer at all for this expression.
In your case, if all the low-end bits of s are set, then t will grow to be
32 without the test failing (even assuming a logical shift ala BC). 
When t is equal to or greater than 32, the value of (s << t) no longer has
any definition, so you are again depending on the behaviour of one specific
platform.

But you don't really explain
in your post what you consider to be the 'right' answer. As far as I can
see, you are attempting to count the number of zero bits in the least-significant
part of s. An alternative means of doing this is to use a mask of 1
and shift that, testing it against your value and exiting when it produces
a non-zero result, or when you have done too many shifts.

for(x = 1,nz = 0; nz != sizeof(int)*8 && (x & s) == 0; x = x << 1,nz++;)  ;
 
 at the end of this loop, nz contains the number of zero bits (i.e. 32 - t)
 I've used sizeof(int) in this example so the code will be a bit more
immune to porting to non 32-bit platforms.
 
------------------------------------------------------------------------------
Kevin Ashley                                       K DOT Ashley AT Ulcc DOT ac DOT uk
Special Projects Manager             http://www.ulcc.ac.uk/staff/Kevin+Ashley
ULCC                        ...ukc!ncdlab!K.Ashley (but probably not any more)
                      This is not a signature

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019