initializing int to a number bigger than INT_MAX

Discussion in 'C Programming' started by vikky@gmail.com, Apr 12, 2005.

  1. Guest

    hi all,
    Out of sheer curosity, I decided to initialize an integer with a number
    bigger than INT_MAX, however I still am not able to justify its output.
    Here is the program :

    #include<stdio.h>

    int main(void)
    {
    int t=0xFFFFFFFFFFFFFFFFDABC;
    printf("t is : %x\n",t);
    getchar();
    return 0;
    }
    I ran this program using Dev-C++ in Windows on x86( gcc.exe
    "C:\Untitled.c" -o "C:\Untitled.exe" -Wall -pg -g3
    -I"C:\Dev-Cpp\include" -L"C:\Dev-Cpp\lib" -lgmon -pg -g3)

    The output was
    t is : ffffdabc

    What is happening in here?
    And even if I write
    int t=0xFFFCFDFAFFFFFFFFDABC;
    it is giving the same output. Infact even if i increase any hex digit
    at beginning(like int t=0xFFAAAAFFFFFFFFFFFFFFDABC;) it is giving the
    same output.

    I guess its some kind of truncation going on .. but then why is it
    ignoring MSBs ? I am also guessing this behaviour is compiler dependent
    - am i correct?
     
    , Apr 12, 2005
    #1
    1. Advertising

  2. jeff_hann Guest

    wrote:
    > hi all,
    > Out of sheer curosity, I decided to initialize an integer with a

    number
    > bigger than INT_MAX, however I still am not able to justify its

    output.
    > Here is the program :
    >
    > #include<stdio.h>
    >
    > int main(void)
    > {
    > int t=0xFFFFFFFFFFFFFFFFDABC;
    > printf("t is : %x\n",t);
    > getchar();
    > return 0;
    > }
    > I ran this program using Dev-C++ in Windows on x86( gcc.exe
    > "C:\Untitled.c" -o "C:\Untitled.exe" -Wall -pg -g3
    > -I"C:\Dev-Cpp\include" -L"C:\Dev-Cpp\lib" -lgmon -pg -g3)
    >
    > The output was
    > t is : ffffdabc
    >
    > What is happening in here?
    > And even if I write
    > int t=0xFFFCFDFAFFFFFFFFDABC;
    > it is giving the same output. Infact even if i increase any hex digit
    > at beginning(like int t=0xFFAAAAFFFFFFFFFFFFFFDABC;) it is giving the
    > same output.
    >
    > I guess its some kind of truncation going on .. but then why is it
    > ignoring MSBs ? I am also guessing this behaviour is compiler

    dependent
    > - am i correct?
     
    jeff_hann, Apr 12, 2005
    #2
    1. Advertising

  3. jeff_hann Guest

    wrote:
    > hi all,
    > Out of sheer curosity, I decided to initialize an integer with a

    number
    > bigger than INT_MAX, however I still am not able to justify its

    output.
    > Here is the program :
    >
    > #include<stdio.h>
    >
    > int main(void)
    > {
    > int t=0xFFFFFFFFFFFFFFFFDABC;
    > printf("t is : %x\n",t);
    > getchar();
    > return 0;
    > }
    > I ran this program using Dev-C++ in Windows on x86( gcc.exe
    > "C:\Untitled.c" -o "C:\Untitled.exe" -Wall -pg -g3
    > -I"C:\Dev-Cpp\include" -L"C:\Dev-Cpp\lib" -lgmon -pg -g3)
    >
    > The output was
    > t is : ffffdabc
    >
    > What is happening in here?
    > And even if I write
    > int t=0xFFFCFDFAFFFFFFFFDABC;
    > it is giving the same output. Infact even if i increase any hex digit
    > at beginning(like int t=0xFFAAAAFFFFFFFFFFFFFFDABC;) it is giving the
    > same output.
    >
    > I guess its some kind of truncation going on .. but then why is it
    > ignoring MSBs ? I am also guessing this behaviour is compiler

    dependent
    > - am i correct?


    Hi,
    First of all,I think it is[like you said] compiler/platform -
    dependent,so,it's
    a little OT.Second,why 'getchar()'?And third,this is,in my humble
    opinion,clearly undefined.
     
    jeff_hann, Apr 12, 2005
    #3
  4. On Tue, 12 Apr 2005 09:29:35 -0700, said to the parser:

    > hi all,
    > Out of sheer curosity, I decided to initialize an integer with a number
    > bigger than INT_MAX, however I still am not able to justify its output.
    > Here is the program :
    >
    > int t=0xFFFFFFFFFFFFFFFFDABC;


    First of all, this is in fact *smaller* than INT_MAX. What you've
    written is a negative number, as you're using a signed int. All the
    extra leading Fs, above and beyond the 32-bit limit of your architecture,
    in binary terms, are leading ones, which can "safely" be "dropped" and
    still yield the same 2s-complement number in a "lower int-sized" machine,
    assuming the meaningful bits of the number are small enough to fit.

    Hmmm, I didn't explain that very well, but...

    I'm surprised you would know of the existence of INT_MAX, yet
    don't seem to follow what it means.

    INT...
    MAX...

    It's the maximum size int you can declare.

    I suspect that on your hardware, INT_MAX is 0x7FFF FFFF, or 2,147,483,647.

    INT_MIN will be declared as -INT_MAX-1 or -2,147,483,648.

    So by trying to enter more than 32 bits into your declared int, it's
    getting truncated to the lowest 32 bits, 0xFFFFDABC, or -9540.

    Note that 0xFFFF FFFF is the "largest" hexadecimal value that can be held
    by an int on your architecture. Note also that for a signed int, this is
    actually -1.

    > I guess its some kind of truncation going on .. but then why is it
    > ignoring MSBs ? I am also guessing this behaviour is compiler dependent
    > - am i correct?


    In so far as INT_MAX and INT_MIN will change from compiler to compiler and
    architecture to architecture, yes.


    Michael
     
    Michael Coyne, Apr 12, 2005
    #4
  5. "" <> writes:
    > hi all,
    > Out of sheer curosity, I decided to initialize an integer with a number
    > bigger than INT_MAX, however I still am not able to justify its output.
    > Here is the program :
    >
    > #include<stdio.h>
    >
    > int main(void)
    > {
    > int t=0xFFFFFFFFFFFFFFFFDABC;
    > printf("t is : %x\n",t);
    > getchar();
    > return 0;
    > }

    [snip]
    > The output was
    > t is : ffffdabc

    [snip]

    Strictly speaking, the "%x" specifier expects an unsigned int. You
    can almost certainly get away with passing an int, but I still prefer
    to use an explicit cast (one of the few cases where casts are useful):

    printf("t is : %x\n", (unsigned)t);

    The literal 0xFFFFFFFFFFFFFFFFDABC requires 80 bits, which is probably
    (but not certainly) larger than any integer type.

    An unsuffixed hexadecimal integer constant's type is the first type
    from this list:

    int
    unsigned int
    long int
    unsigned long int
    long long int (C99 only)
    unsigned long long int (C99 only)

    in which the value can be represented. If it can't be represented in
    any of those types, it may have an extended integer type (if the
    implementation has extended integer types; I don't know of any that
    do). If there is no type that can represent the value, the standard
    doesn't say what its type is; I believe this means it invokes
    undefined behavior by omission (i.e., the behavior is undefined not
    because the standard says so, but because it fails to define the
    behavior).

    I'd be happier if the standard said something explicit about integer
    constants that can't be represented in any type.

    On the other hand, suppose you use a literal that fits in some integer
    type, but not in int. For example, assuming 32-bit int and long, and
    64-bit long long:

    int t = 0xFFFFFFFFFFFFDABC; /* 64 bits */

    the constant is of type unsigned long long. The value is implicitly
    converted to type int before being used to initialize t. An
    overflowing conversion to a signed integer type doesn't invoke
    undefined behavior; it merely yields an implementation-defined result
    or raises an implementation-defined signal. (In C90, it yields an
    undefined result; there's no mention of raising a signal.)

    Having said all that, on every implementation I know of a conversion
    from a larger to a smaller integer type simply discards the high-order
    bits. You shouldn't depend on this behavior in portable code.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 12, 2005
    #5
  6. Eric Sosman Guest

    Michael Coyne wrote:
    > On Tue, 12 Apr 2005 09:29:35 -0700, said to the parser:
    >
    >
    >>hi all,
    >>Out of sheer curosity, I decided to initialize an integer with a number
    >>bigger than INT_MAX, however I still am not able to justify its output.
    >>Here is the program :
    >>
    >> int t=0xFFFFFFFFFFFFFFFFDABC;

    >
    >
    > First of all, this is in fact *smaller* than INT_MAX. What you've
    > written is a negative number, as you're using a signed int. All the
    > extra leading Fs, above and beyond the 32-bit limit of your architecture,
    > in binary terms, are leading ones, which can "safely" be "dropped" and
    > still yield the same 2s-complement number in a "lower int-sized" machine,
    > assuming the meaningful bits of the number are small enough to fit.
    >
    > Hmmm, I didn't explain that very well, but...


    No, indeed: Much of what you wrote was incorrect.

    To begin with, the hexadecimal constant is a large
    *positive* number. In fact, all numeric[*] constants in C
    are non-negative. The problems here are (1) that the big
    hex constant may be too large for any integral data type
    supported by the implementation, and (2) even if that's
    not the case, it may be bigger than INT_MAX.

    Case 1 may apply even though the compiler didn't
    complain; I can't find anything in the Standard that seems
    to require a diagnostic for out-of-range constants. If
    case 1 applies, we really can't tell for sure what happened,
    but it looks like the compiler may have mangled the value
    (along the lines you describe, and that part of your answer
    was correct -- for two's complement machines, anyhow).

    If it's case 2, initialization is "as if" by conversion
    of the very large value to `int'. Converting an out-of-range
    value to `int' produces an implementation-defined result (or
    raises an implementation-defined signal). On two's complement
    machines it is likely that the implementation-defined result
    will be "chopped" in the way you describe, but this is not
    guaranteed by the Standard.

    [*] The only negative constants I can think of are enum
    values specifically declared as negative, and character or
    wide-character constants involving "extra" characters not
    in the basic execution set (and even then only if `char' or
    `wchar_t' is signed). Constants that "look like" numbers
    are non-negative.

    --
     
    Eric Sosman, Apr 12, 2005
    #6
  7. Keith Thompson <> writes:
    [...]
    > An unsuffixed hexadecimal integer constant's type is the first type
    > from this list:
    >
    > int
    > unsigned int
    > long int
    > unsigned long int
    > long long int (C99 only)
    > unsigned long long int (C99 only)
    >
    > in which the value can be represented. If it can't be represented in
    > any of those types, it may have an extended integer type (if the
    > implementation has extended integer types; I don't know of any that
    > do). If there is no type that can represent the value, the standard
    > doesn't say what its type is; I believe this means it invokes
    > undefined behavior by omission (i.e., the behavior is undefined not
    > because the standard says so, but because it fails to define the
    > behavior).
    >
    > I'd be happier if the standard said something explicit about integer
    > constants that can't be represented in any type.

    [...]

    I posted a question about this in comp.std.c, and Wojtek Lerch pointed
    me to a constraint in C99 6.4.4p2:

    The value of a constant shall be in the range of representable
    values for its type.

    I think this could be worded better (there's no such thing as "its
    type", since 6.4.4.1 doesn't define a type for an integer constant
    that can't be represented), but it's clear enough that it's intended
    to be a constraint violation.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 13, 2005
    #7
  8. On 12 Apr 2005 09:29:35 -0700, ""
    <> wrote:

    > hi all,
    > Out of sheer curosity, I decided to initialize an integer with a number
    > bigger than INT_MAX, however I still am not able to justify its output.

    <snip example>
    > What is happening in here? <snip>
    > I guess its some kind of truncation going on .. but then why is it
    > ignoring MSBs ? I am also guessing this behaviour is compiler dependent
    > - am i correct?


    Your guesses are right. Converting to a signed integer type a value
    (of a wider integer type) that doesn't fit produces an
    implementation-defined result, or in C99 possibly raises an
    implementation-defined signal. It is very common, though not required,
    to just take the lower bits, because that efficiently gives the
    correct (required) result for values that _do_ fit, and the same logic
    works for unsigned types which are required to take the low bits of an
    unsigned or 2s-complement representation. (Officially unsigned takes
    the 'modulo' value, but for 2sC that equals the low bits. The very few
    if any S&M or 1sC machines must do something more complicated.)

    Implementation-defined does mean that the documentation associated
    with the implementation must specify what it does.

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Apr 18, 2005
    #8
    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. Schnoffos
    Replies:
    2
    Views:
    1,254
    Martien Verbruggen
    Jun 27, 2003
  2. Dave Huang
    Replies:
    1
    Views:
    399
    =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
    Mar 27, 2005
  3. Replies:
    3
    Views:
    399
  4. Replies:
    2
    Views:
    796
    Filip Larsen
    Apr 10, 2007
  5. Yannick Turgeon

    App getting bigger and bigger

    Yannick Turgeon, Oct 13, 2003, in forum: Perl Misc
    Replies:
    1
    Views:
    150
    Yannick Turgeon
    Oct 14, 2003
Loading...

Share This Page