decimal constant too large

Discussion in 'C Programming' started by kerravon, Nov 10, 2007.

  1. kerravon

    kerravon Guest

    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.

    Any ideas? I checked the FAQ but didn't see anything.

    Thanks. Paul.
    kerravon, Nov 10, 2007
    #1
    1. Advertising

  2. kerravon

    Chris Dollin Guest

    kerravon wrote:

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


    `-2147483648` isn't a decimal constant; it's an expression. The decimal
    constant in question is `2147483648`, which is one bigger than can be
    expressed in a 32-bit signed integer.

    --
    Compiler 15, OP love Hedgehog
    "It took a very long time, much longer than the most generous estimates."
    - James White, /Sector General/
    Chris Dollin, Nov 10, 2007
    #2
    1. Advertising

  3. kerravon

    kerravon Guest

    On Nov 10, 10:30 pm, Chris Dollin <> wrote:
    > kerravon wrote:
    > > 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.

    >
    > `-2147483648` isn't a decimal constant; it's an expression. The decimal
    > constant in question is `2147483648`, which is one bigger than can be
    > expressed in a 32-bit signed integer.


    I see. So is the solution then to make it -2147483648U ?

    I can see from other people's limits.h that they have made it
    (-2147483647-1). Why would they do that instead of sticking a U
    on the end? Is it because the U on the end will force everything
    into unsigned arithmetic?

    Thanks. Paul.
    kerravon, Nov 10, 2007
    #3
  4. On Sat, 10 Nov 2007 03:08:03 -0800,
    kerravon <> wrote:
    > 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


    Assuming that you're right and that INT_MIN on your system is indeed
    -2147483648 (and INT_MAX 2147483647):

    I suspect that gcc sees the constant as two tokens: '-' and 2147483648.
    2147483648 is larger than INT_MAX, which is what probably
    triggers the warning. Try to see if the warning goes away if you write:

    int x = -INT_MAX - 1;

    Martien
    --
    |
    Martien Verbruggen | prepBut nI vrbLike adjHungarian! qWhat's
    | artThe adjBig nProblem? -- Alec Flett
    |
    Martien Verbruggen, Nov 10, 2007
    #4
  5. kerravon <> 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.

    The best way to at you system limits is with:

    #include <limits.h>

    There you will find INT_MIN. On my system, its definition is
    (-INT_MAX - 1). Can see how this avoids any overflow?

    There was a subtle change in C99 -- the number 2147483648 must be
    interpreted as having type 'signed long long int'. Both because long
    long was introduced but also because the rules about what constants
    are taken to be signed and unsigned were changed. Thus in C99 there
    is no overflow since the negated long long int does, just, fit into an
    int.

    Obviously the numbers will be different on systems with other integer
    sizes.

    --
    Ben.
    Ben Bacarisse, Nov 10, 2007
    #5
  6. kerravon

    James Kuyper Guest

    kerravon wrote:
    > On Nov 10, 10:30 pm, Chris Dollin <> wrote:

    ....
    >> `-2147483648` isn't a decimal constant; it's an expression. The decimal
    >> constant in question is `2147483648`, which is one bigger than can be
    >> expressed in a 32-bit signed integer.

    >
    > I see. So is the solution then to make it -2147483648U ?


    No, -2147483648U is an expression containing the unary '-' operator
    acting on an unsigned integer; the result will therefore also have an
    unsigned integer type, and therefore a positive value.

    > I can see from other people's limits.h that they have made it
    > (-2147483647-1). Why would they do that instead of sticking a U
    > on the end? Is it because the U on the end will force everything
    > into unsigned arithmetic?


    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.
    James Kuyper, Nov 10, 2007
    #6
  7. kerravon

    Serve Lau Guest

    "Ben Bacarisse" <> wrote in message
    news:...
    > There was a subtle change in C99 -- the number 2147483648 must be
    > interpreted as having type 'signed long long int'. Both because long
    > long was introduced but also because the rules about what constants
    > are taken to be signed and unsigned were changed.


    Can you generalize this a bit more?

    Every integer constant is taken as a long long in C99?
    Serve Lau, Nov 10, 2007
    #7
  8. kerravon

    CBFalconer Guest

    kerravon wrote:
    >
    > 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.


    The expression consists of the positive integer 2147483648 and a
    negation. The positive integer doesn't fit. You can form the
    value with "-2147483648 - 1" on 32 bit systems. On 16 bit (or 31
    bit, etc.) systems you will need to use a long.

    Another option is:

    int x = INT_MIN;

    after #include <limits.h>

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.


    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Nov 10, 2007
    #8
  9. "Serve Lau" <> writes:

    > "Ben Bacarisse" <> wrote in message
    > news:...
    >> There was a subtle change in C99 -- the number 2147483648 must be
    >> interpreted as having type 'signed long long int'. Both because long
    >> long was introduced but also because the rules about what constants
    >> are taken to be signed and unsigned were changed.

    >
    > Can you generalize this a bit more?
    >
    > Every integer constant is taken as a long long in C99?


    No. A decimal constant that has no suffix (u, l, etc) will be taken
    to be the first of int, long int, long long int that can represent the
    value. The full description of how suffixes and prefixes (denoting
    octal and hex constants) affect the resulting type is best described
    as in it in the standard -- as a table. Octal and hex constants can
    either unsigned or signed and the suffixes impose the obvious
    restrictions but the table is the clearest way of seeing it all.

    In C90 an unadorned decimal constant has type int, long int or
    unsigned long int, whichever is the first to be able to represent the
    value. Apart from the fact C90 has no long long types, this is
    pretty much the only difference.

    --
    Ben.
    Ben Bacarisse, Nov 10, 2007
    #9
  10. kerravon

    James Kuyper Guest

    Serve Lau wrote:
    > "Ben Bacarisse" <> wrote in message
    > news:...
    >> There was a subtle change in C99 -- the number 2147483648 must be
    >> interpreted as having type 'signed long long int'. Both because long
    >> long was introduced but also because the rules about what constants
    >> are taken to be signed and unsigned were changed.

    >
    > Can you generalize this a bit more?
    >
    > Every integer constant is taken as a long long in C99?


    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.

    The rules for determining the type of an integer constant are given in
    section 6.4.4.1p5 and p6. They depend upon many things. It's unsigned if
    a 'U' or a 'u' suffix is applied, and it's at least as big as a long if
    an 'L' or 'l' suffix is applied, and it's at least as big as a long long
    if an 'LL' or 'll' suffix is used. Decimal constants have an unsigned
    type only if explicitly labeled with the 'U' or 'u' suffix, or if they
    are too big for long long. In contrast, octal and hexadecimal constants
    without that suffix can have either a signed or unsigned type. Within
    those constraints, the type of an integer constant is generally the
    smallest standard type that is big enough to represent that value,
    except that is never a type smaller than 'int'. If none of the standard
    types is big enough to hold the specified value, an extended integer
    type can be used instead.
    James Kuyper, Nov 10, 2007
    #10
  11. kerravon

    Joe Wright Guest

    CBFalconer wrote:
    > kerravon wrote:
    >> 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.

    >
    > The expression consists of the positive integer 2147483648 and a
    > negation. The positive integer doesn't fit. You can form the
    > value with "-2147483648 - 1" on 32 bit systems. On 16 bit (or 31
    > bit, etc.) systems you will need to use a long.
    >
    > Another option is:
    >
    > int x = INT_MIN;
    >
    > after #include <limits.h>
    >

    Off-by-one? From my limits.h

    #define INT_MAX 2147483647
    #define INT_MIN (-2147483647-1)

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Nov 10, 2007
    #11
  12. Joe Wright <> writes:
    > CBFalconer wrote:
    >> kerravon wrote:
    >>> 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

    [snip]
    >> Another option is:
    >> int x = INT_MIN;
    >> after #include <limits.h>
    >>

    > Off-by-one? From my limits.h
    >
    > #define INT_MAX 2147483647
    > #define INT_MIN (-2147483647-1)


    I don't see an off-by-one error. The OP wanted to initialize x to the
    value -2147483648. If INT_MIN is defined as above, then
    int x = INT_MIN;
    is one correct way to do that.

    (Two's-complement representations generally do have an extra negative
    value.)

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Nov 10, 2007
    #12
  13. James Kuyper <> writes:
    > kerravon wrote:
    >> On Nov 10, 10:30 pm, Chris Dollin <> wrote:

    > ...
    >>> `-2147483648` isn't a decimal constant; it's an expression. The decimal
    >>> constant in question is `2147483648`, which is one bigger than can be
    >>> expressed in a 32-bit signed integer.

    >> I see. So is the solution then to make it -2147483648U ?

    >
    > No, -2147483648U is an expression containing the unary '-' operator
    > acting on an unsigned integer; the result will therefore also have an
    > unsigned integer type, and therefore a positive value.


    I'll assume in the following that:
    INT_MIN is -2147483648
    INT_MAX is 2147483647
    UINT_MAX is 4294967295
    The numbers above represent numeric values, not necessarily valid C
    expressions.

    Specifically, given the above assumtions, -2147483648U will have the
    value 2147483648U. Negating an unsigned value is equivalent to
    subtracting that value from the maximum value of the type plus one.
    (For the same reason, -1U has the value 4294967295U.)

    If you use the value 2147483648U to initialize an object of type int,
    the value must be converted from unsigned int to int. Since the
    numeric value 2147483648 is too be to be stored in an int, the result
    is implementation-defined (or, in C99, an implementation-defined
    signal might be raised). In other words, don't do this if you care
    about the portability of your code.

    (On a typical two's-complement implementation, converting 2147483648U
    to int yields the int value -2147483648, which is exactly what you
    want -- but it's not guaranteed by the language, which is why the
    compiler is warning you about it.)

    >> I can see from other people's limits.h that they have made it
    >> (-2147483647-1). Why would they do that instead of sticking a U
    >> on the end? Is it because the U on the end will force everything
    >> into unsigned arithmetic?

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


    Right.

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Nov 10, 2007
    #13
  14. On Sat, 10 Nov 2007 12:59:08 -0800, Keith Thompson wrote:
    > Joe Wright <> writes:
    >> CBFalconer wrote:
    >>> kerravon wrote:
    >>>> 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

    > [snip]

    [un-snip]
    >>>
    >>> The expression consists of the positive integer 2147483648 and a
    >>> negation. The positive integer doesn't fit. You can form the
    >>> value with "-2147483648 - 1" on 32 bit systems. On 16 bit (or 31
    >>> bit, etc.) systems you will need to use a long.
    >>>

    [end un-snip]
    >>
    >> Off-by-one?

    >
    > I don't see an off-by-one error.


    The value can be formed with -2147483647 - 1, not -2147483648 - 1.
    =?iso-2022-kr?q?Harald_van_D=0E=29=26=0Fk?=, Nov 10, 2007
    #14
  15. kerravon

    Bartc Guest

    "James Kuyper" <> 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?

    Bart
    Bartc, Nov 10, 2007
    #15
  16. "Harald van D)&k" <> writes:
    > On Sat, 10 Nov 2007 12:59:08 -0800, Keith Thompson wrote:
    >> Joe Wright <> writes:
    >>> CBFalconer wrote:

    [snip]
    >>>> The expression consists of the positive integer 2147483648 and a
    >>>> negation. The positive integer doesn't fit. You can form the
    >>>> value with "-2147483648 - 1" on 32 bit systems. On 16 bit (or 31
    >>>> bit, etc.) systems you will need to use a long.
    >>>>

    > [end un-snip]
    >>>
    >>> Off-by-one?

    >>
    >> I don't see an off-by-one error.

    >
    > The value can be formed with -2147483647 - 1, not -2147483648 - 1.


    D'oh! You're right; I misread the "-2147483647 - 1"" in CBFalconer's
    post as ""-2147483647 - 1".

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Nov 10, 2007
    #16
  17. "Bartc" <> writes:
    > "James Kuyper" <> 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?


    A hexadecimal constant doesn't specify a bit pattern; it specifies a
    *value*, just as a decimal constant does. The rules for determining
    the type vary somewhat for decimal vs. hexadecimal (and for C90
    vs. C99).

    In C99, the type of a hexadecimal constant is the first of:
    int
    unsigned int
    long int
    unsigned long int
    long long int
    unsigned long long int
    which can hold the value. For 0x80000000, assuming 32-bit int, the
    result is unsigned int, which creates the same conversion problems as
    2147483648U or -2147483648U.

    In C90, the sequence is the same except for the omission of long long
    int and unsigned long long int, which don't affect this case.

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Nov 10, 2007
    #17
  18. kerravon

    Joe Wright Guest

    Keith Thompson wrote:
    > Joe Wright <> writes:
    >> CBFalconer wrote:
    >>> kerravon wrote:
    >>>> 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

    > [snip]
    >>> Another option is:
    >>> int x = INT_MIN;
    >>> after #include <limits.h>
    >>>

    >> Off-by-one? From my limits.h
    >>
    >> #define INT_MAX 2147483647
    >> #define INT_MIN (-2147483647-1)

    >
    > I don't see an off-by-one error. The OP wanted to initialize x to the
    > value -2147483648. If INT_MIN is defined as above, then
    > int x = INT_MIN;
    > is one correct way to do that.
    >
    > (Two's-complement representations generally do have an extra negative
    > value.)
    >

    Chuck suggested "-2147483648 - 1" which is 'off-by-one' I'd say.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Nov 11, 2007
    #18
  19. kerravon

    CBFalconer Guest

    Keith Thompson wrote:
    > "Harald van D)&k" <> writes:
    >> Keith Thompson wrote:
    >>> Joe Wright <> writes:
    >>>> CBFalconer wrote:

    > [snip]
    >>>>> The expression consists of the positive integer 2147483648 and a
    >>>>> negation. The positive integer doesn't fit. You can form the
    >>>>> value with "-2147483648 - 1" on 32 bit systems. On 16 bit (or 31
    >>>>> bit, etc.) systems you will need to use a long.
    >>>>>

    >> [end un-snip]
    >>>>
    >>>> Off-by-one?
    >>>
    >>> I don't see an off-by-one error.

    >>
    >> The value can be formed with -2147483647 - 1, not -2147483648 - 1.

    >
    > D'oh! You're right; I misread the "-2147483647 - 1"" in CBFalconer's
    > post as ""-2147483647 - 1".


    One lousy type has generated at least 3, probably more, discussion
    messages. 7 != 8. :)

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Nov 11, 2007
    #19
  20. kerravon

    Jack Klein Guest

    On Sat, 10 Nov 2007 11:49:47 +0000, Ben Bacarisse
    <> wrote in comp.lang.c:

    > kerravon <> 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.

    If that value is outside the range of a signed int and used to
    initialize one, the result is implementation-defined.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Nov 11, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luigi Donatello Asero

    Are these pictures too dark or/and too large?

    Luigi Donatello Asero, May 19, 2004, in forum: HTML
    Replies:
    13
    Views:
    899
    Mabden
    May 21, 2004
  2. Luigi Donatello Asero

    Re: Are these pictures too dark or/and too large?

    Luigi Donatello Asero, May 21, 2004, in forum: HTML
    Replies:
    0
    Views:
    636
    Luigi Donatello Asero
    May 21, 2004
  3. Jo Deni
    Replies:
    7
    Views:
    18,739
    Old Wolf
    Aug 13, 2007
  4. Guest
    Replies:
    1
    Views:
    362
    Alexey Smirnov
    Sep 30, 2008
  5. shin82

    problem with constant too too large

    shin82, Oct 31, 2012, in forum: C Programming
    Replies:
    0
    Views:
    341
    shin82
    Oct 31, 2012
Loading...

Share This Page