Velocity Reviews > decimal constant too large

# decimal constant too large

Ben Pfaff
Guest
Posts: n/a

 11-11-2007
Jack Klein <(E-Mail Removed)> writes:
> The result of negating an unsigned integer has a well-defined
> result, namely UINT_MAX - value.

UINT_MAX - value + 1
--
Ben Pfaff
http://benpfaff.org

Keith Thompson
Guest
Posts: n/a

 11-11-2007
Jack Klein <(E-Mail Removed)> writes:
> On Sat, 10 Nov 2007 11:49:47 +0000, Ben Bacarisse
> <(E-Mail Removed)> wrote in comp.lang.c:
>> kerravon <(E-Mail Removed)> writes:
>> > The following C program:
>> >
>> > int main(void)
>> > {
>> > int x = -2147483648;
>> >
>> > return (0);
>> > }

[...]
>>
>> Except C has no negative literals. Your initializer is an expression:
>> the unary negation operator is applied to a constant. That constant,
>> 2147483648, is indeed so large that it is unsigned (in C90). Negating
>> this large unsigned number provokes, technically, integer overflow.

>
> No, arithmetic on unsigned types never overflows. The result of
> negating an unsigned integer has a well-defined result, namely
> UINT_MAX - value.
>
> If that value is outside the range of a signed int and used to
> initialize one, the result is implementation-defined.

Interesting. This is a change from C90 to C99.

In C90, an unsuffixed decimal integer constant's type is the first of
int
unsigned int
long int
unsigned long int
in which it will fit.

In C99, the list is
int
long int
long long int

So in C99, unlike in C90, an unsuffixed decimal integer constant can
never be of an unsigned type.

So if INT_MAX and LONG_MAX are both 2147483647, then the constant
2147483648 is of type unsigned int in C90 and of type long long int in
C99. In C90:
int x = -2147483648;
converts the unsigned int value 2147483648 to int, which yields an
implementation-defined result. But in C99, it converts the long long
int value -2147483648 to type int, which is well defined.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Flash Gordon
Guest
Posts: n/a

 11-11-2007
Ben Pfaff wrote, On 11/11/07 04:34:
> Jack Klein <(E-Mail Removed)> writes:
>> The result of negating an unsigned integer has a well-defined
>> result, namely UINT_MAX - value.

>
> UINT_MAX - value + 1

For operations other than negations (being talked about above),
subtraction and addition repeat until it is in range. UINT_MAX * 5 will
need the repeat
--
Flash Gordon

Serve Lau
Guest
Posts: n/a

 11-11-2007

"James Kuyper" <(E-Mail Removed)> wrote in message
news:9clZi.284\$Y32.8@trnddc04...
> No - what he said is based upon the implied assumption that LONG_MAX is
> 2147483647. If LONG_MAX > 2147483647, then the type of 2147483648 could be
> long int. If INT_MAX > 2147483647, the type of 2147483648 would be plain
> int.

I see, so then LLONG_MIN will probably be defined as follows in C99

#define LLONG_MIN (-LLONG_MAX-1LL)

Ben Bacarisse
Guest
Posts: n/a

 11-11-2007
Jack Klein <(E-Mail Removed)> writes:

> On Sat, 10 Nov 2007 11:49:47 +0000, Ben Bacarisse
> <(E-Mail Removed)> wrote in comp.lang.c:
>
>> kerravon <(E-Mail Removed)> writes:
>>
>> > The following C program:
>> >
>> > int main(void)
>> > {
>> > int x = -2147483648;
>> >
>> > return (0);
>> > }
>> >
>> > Produces the following warning:
>> >
>> > temp.c: In function `main':
>> > temp.c:3: warning: decimal constant is so large that it is unsigned
>> >
>> > on gcc on Win98 and MVS.
>> >
>> > As far as I can tell, that is in fact the maximum negative number on
>> > those environments and therefore the constant fits into a signed
>> > integer and therefore I shouldn't be getting a warning.

>>
>> Except C has no negative literals. Your initializer is an expression:
>> the unary negation operator is applied to a constant. That constant,
>> 2147483648, is indeed so large that it is unsigned (in C90). Negating
>> this large unsigned number provokes, technically, integer overflow.

>
> No, arithmetic on unsigned types never overflows. The result of
> negating an unsigned integer has a well-defined result, namely
> UINT_MAX - value.

(ITYM UINT_MAX + 1 - value)

Silly of me. Having pointed out that the constant is unsigned I
should been able to follow through. This is an old "gotcha" with C90.
While, to the initiated, it is clear that negated unsigned values are
never negative (they are just ways to write values calculated form
Uxxx_MAX + 1) it is easy to forget that some large integer constants
are also unsigned.

Frequent users of C are not phased by -1U, -2U etc being positive, but
one can be surprised to find two out of -2147483647, -2147483648 and
-2147483649 are positive (in C90). I think C99's position (where all
three of these are negative on the architecture in question) is much
clearer.

PS. I know you know this. I am typing it as way to anchor it for me!

--
Ben.

Joe Wright
Guest
Posts: n/a

 11-11-2007
Serve Lau wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:9clZi.284\$Y32.8@trnddc04...
>> No - what he said is based upon the implied assumption that LONG_MAX is
>> 2147483647. If LONG_MAX > 2147483647, then the type of 2147483648 could be
>> long int. If INT_MAX > 2147483647, the type of 2147483648 would be plain
>> int.

>
> I see, so then LLONG_MIN will probably be defined as follows in C99
>
> #define LLONG_MIN (-LLONG_MAX-1LL)
>
>

/* constants used in Solaris */
#define LLONG_MIN (-9223372036854775807LL-1LL)
#define LLONG_MAX 9223372036854775807LL
#define ULLONG_MAX 18446744073709551615ULL
/* gnuc ones */
#define LONG_LONG_MIN LLONG_MIN
#define LONG_LONG_MAX LLONG_MAX
#define ULONG_LONG_MAX ULLONG_MAX

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

Charlie Gordon
Guest
Posts: n/a

 11-12-2007
"Bartc" <(E-Mail Removed)> a écrit dans le message de news:
FiqZi.254407\$(E-Mail Removed). ..
>
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:aKjZi.2772\$CI1.80@trnddc03...
>
>> Yes, that is the reason. When the mathematical value of INT_MIN
>> is -2147483648, the C expression (-2147483647-1) is one of the simplest
>> expressions that has that value.

>
> Is it not possible to use a hex constant such as 0x80000000? Would that be
> treated as a bit-pattern that includes the sign bit?

With INT_MAX == 2147483647 and INT_MIN == (-2147483647-1), 0x80000000 has
type unsigned int. It would behave differently from (-2147483647-1) in
expressions like ``0x80000000 < 0'' that evaluates to 0 instead of
``(-2147483647-1) < 0'' that evaluates to 1. Whether it converts to the
same value when cast to (int) is not even defined by the standard, but in
does so in all common 32 bit architectures.

--
Chqrlie.