Arithmetic/Comparison between different integer types

Discussion in 'C++' started by Frederick Gotham, Jul 7, 2006.

  1. I just want to clarify my understanding of arithmetic and comparison
    between two different integer types.


    Phase (1): Integer Promotion
    ----------

    All of the following types always get promoted to "signed int":

    signed char
    signed short

    All of the following types get promoted to "signed int" if it has
    sufficient range on the platform; otherwise, they go to "unsigned int".

    char
    unsigned char
    unsigned short


    Phase (2): Now working with "int" and upwards
    ----------

    Now everything is one of the following types:

    signed int
    unsigned int
    signed long
    unsigned long

    That leaves us with 10 possibilities. The first four are straight-forward:

    (1) signed int + signed int
    (2) unsigned int + unsigned int
    (3) signed long + signed long
    (4) unsigned long + unsigned long

    The following involve the same type, but different signedness. Am I right
    in thinking that they both become "unsigned int" in (5), and both become
    "unsigned long" in (6)?

    (5) signed int + unsigned int
    (6) signed long + unsigned long


    Then there's two different types which have the same signedness. Would I be
    right in thinking that they both become signed long in (7), and both become
    unsigned long in (8)?

    (7) signed int + signed long
    (8) unsigned int + unsigned long

    Now here's the dirty ones which I'm least sure about. What happens in (9)
    and (10)? Are (9) and (10) implementation-specific depending on whether
    numeric_limits<long>::digits > numeric_limits<int>::digits?

    (9) signed int + unsigned long
    (10) unsigned int + signed long


    --

    Frederick Gotham
    Frederick Gotham, Jul 7, 2006
    #1
    1. Advertising

  2. "Frederick Gotham" <> wrote:

    > I just want to clarify my understanding of arithmetic and comparison
    > between two different integer types.
    >
    >
    > Phase (1): Integer Promotion
    > ----------
    >
    > All of the following types always get promoted to "signed int":
    >
    > signed char
    > signed short
    >
    > All of the following types get promoted to "signed int" if it has
    > sufficient range on the platform; otherwise, they go to "unsigned int".
    >
    > char
    > unsigned char
    > unsigned short
    >
    > Phase (2): Now working with "int" and upwards
    > ----------
    >
    > Now everything is one of the following types:
    >
    > signed int
    > unsigned int
    > signed long
    > unsigned long
    >
    > That leaves us with 10 possibilities. The first four are straight-forward:
    >
    > (1) signed int + signed int
    > (2) unsigned int + unsigned int
    > (3) signed long + signed long
    > (4) unsigned long + unsigned long
    >
    > The following involve the same type, but different signedness. Am I right
    > in thinking that they both become "unsigned int" in (5), and both become
    > "unsigned long" in (6)?
    >
    > (5) signed int + unsigned int
    > (6) signed long + unsigned long
    >
    >
    > Then there's two different types which have the same signedness. Would I be
    > right in thinking that they both become signed long in (7), and both become
    > unsigned long in (8)?
    >
    > (7) signed int + signed long
    > (8) unsigned int + unsigned long
    >
    > Now here's the dirty ones which I'm least sure about. What happens in (9)
    > and (10)? Are (9) and (10) implementation-specific depending on whether
    > numeric_limits<long>::digits > numeric_limits<int>::digits?
    >
    > (9) signed int + unsigned long
    > (10) unsigned int + signed long



    The C++ standard, section 5, paragraph 9 reads:


    Many binary operators that expect operands of arithmetic or enumeration
    type cause conversions and yield result types in a similar way. The purpose
    is to yield a common type, which is also the type of the result. This
    pattern is called the usual arithmetic conversions, which are defined as
    follows:
    — If either operand is of type long double, the other shall be converted
    to long double.
    — Otherwise, if either operand is double, the other shall be converted to
    double.
    — Otherwise, if either operand is float, the other shall be converted to
    float.
    — Otherwise, the integral promotions (4.5) shall be performed on both
    operands.54)
    — Then, if either operand is unsigned long the other shall be converted
    to unsigned long.
    — Otherwise, if one operand is a long int and the other unsigned int, then
    if a long int can represent all the values of an unsigned int, the unsigned
    int shall be converted to a long int; otherwise both operands shall be
    converted to unsigned long int.
    — Otherwise, if either operand is long, the other shall be converted to long.
    — Otherwise, if either operand is unsigned, the other shall be converted to
    unsigned.
    [Note: otherwise, the only remaining case is that both operands are int ]


    So most of your cases are set in concrete:
    In your cases 1,2,3,4 no conversions would occur.
    In your case 5, both operands would be converted to unsigned int
    In your cases 6, 8, 9, both operands would be converted to unsigned long.
    In your case 7, both operands would be converted to signed long

    The only case that's implimentation dependent is your case 10.
    If long can represent the values, both operands will be converted to long.
    However, on most modern 32-bit PCs, long can NOT represent all the values
    of unsigned int. Usually the ranges are:
    long: -2147483648 to 2147483647
    unsigned: 0 to 4294967296
    On such machines, in your case 10, both operands will be converted to
    unsigned long int, which is usually identical in range to unsigned int.
    So any negative values will be converted to very large positive values.
    Depending on the application, that could be a disaster or a don't-care.

    --
    Cheers,
    Robbie Hatley
    Tustin, CA, USA
    lonewolfintj at pacbell dot net (put "[ciao]" in subject to bypass spam filter)
    http://home.pacbell.net/earnur/
    Robbie Hatley, Jul 7, 2006
    #2
    1. Advertising

  3. Robbie Hatley posted:

    <snip explanation>


    Thank you, very helpful.

    Now I think I'll go over my code looking for any potential booby traps.


    --

    Frederick Gotham
    Frederick Gotham, Jul 7, 2006
    #3
    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. sieg1974
    Replies:
    8
    Views:
    777
    Joona I Palaste
    Sep 14, 2003
  2. joshc
    Replies:
    5
    Views:
    540
    Keith Thompson
    Mar 31, 2005
  3. Gary Wessle
    Replies:
    4
    Views:
    609
    Ian Collins
    Jul 29, 2006
  4. BarryKamp
    Replies:
    0
    Views:
    602
    BarryKamp
    Apr 25, 2007
  5. Pietro Cerutti

    comparison on non-integer types

    Pietro Cerutti, Sep 5, 2007, in forum: C Programming
    Replies:
    39
    Views:
    1,260
    user923005
    Sep 14, 2007
Loading...

Share This Page