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: 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" 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 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.