www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/04/22/15:09:50

Xref: news2.mv.net comp.os.msdos.djgpp:2954
From: Broeker AT axp05 DOT physik DOT rwth-aachen DOT de (Hans-Bernhard Broeker)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: LONG_MIN question
Date: 22 Apr 96 16:41:32 GMT
Organization: RWTH -Aachen / Rechnerbetrieb Informatik
Lines: 67
Message-ID: <Broeker.830191292@axp05>
References: <01I3RZ7ZOPMQ005280 AT cc DOT uab DOT es>
NNTP-Posting-Host: axp05.physik.rwth-aachen.de
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

"x DOT pons AT cc DOT uab DOT es" <ILGES AT cc DOT uab DOT es> writes:

>Dear programmers,

>If I write a sentence like this: 
>  if (0L < -2147483647L)
                      ^-- I suppose that was a '8', really...
>the result is TRUE, although it should not be. 

Welcome to the world of two's complement representation of negative
integers :-)

>In fact, DJGPP warns it
>when compiling:
>  "warning: decimal constant is so large that it is unsigned"

.... and that should have made clear to you what happened here.  The
source of this problem is that -(LONG_MIN), i.e.  +2147483648, is larger
than LONG_MAX.  Now, if you write -2147483648L, that's parsed as
"-(2147483648L)".  But 2147483648L is *not* a valid long value, and
that's why gcc warned you about it being converted to unsigned long.  So
what gcc really sees here is "(long)(-(2147483468UL))".  Offhand, I'd
guess the value to be either 0 or some *large* positive value (not
exactly sure what gcc does when you apply '-' to a unsigned value). 

Using the notation (-2147483647L - 1L), you can ensure the value
to be generated correctly.

>It is possible to do the right comparison by writing
>  if (0L < LONG_MIN)
>     .....

>LONG_MIN is defined in <limits.h> as:
>   #define LONG_MIN (-2147483647L-1L)

>I suppose this makes the code a bit slower. I'd like to know:

No. It won't slow code down, because this term is always
pre-calculated at compile-time, or at least it should be.

>  1-Is there some way to avoid this subtraction each time I compare a value 
> and -2147483648L

No way, because that value isn't representable otherwise (well, you
could use a union to convert an array of chars to a long value, but
that wouldn't make much difference to the technique described above).

>  2-Why this problem exists? Why doing (-2147483647L-1L) does not produce
>    the same problem?

See above..

>  3-Why DJGPP defines
>      #define SHRT_MIN (-32768)
>    and BC++4.52 defines
>      #define SHRT_MIN (-32767-1)
>    even for 32 bit applications?

For short and normal int's the conversion can be done by using a short
detour throught the unsigned long datatype. For long integers, though,
the detour would have to use the 'unsigned long long' data type, which
it probably doesn't. BC chose to go the safe way and use the above-mentioned
trick for SHRT_MIN as well, but that doesn't really make a difference:
the real compiler output will use a pre-computed binary representation
for these constants anyway.


- Raw text -


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