Subtracting unsigned ints

Discussion in 'C Programming' started by bg_ie@yahoo.com, Jun 20, 2006.

  1. Guest

    Hi,

    I have a function which compares two unsigned ints and returns their
    difference in order to establish which is the greater of the two.

    int Compare(unsigned int time_left, unsigned int time_right)
    {
    return (time_left - time_right);
    }

    usage -

    if( Compare(time_left, time_right) > 0)
    // the time has come.

    The problem is that when time_left is 5 and time_right is 10, I get -5,
    but if time_left is 5 and time_right is 0xc0000005 (a number greater
    than 5) I get a positive value when I wish to get a negitive one.

    I understand why I get this positive value - because the negaitve bit
    is set in time_right, but how can I change my code so that I get the
    desired results.

    Thanks for your help,

    Barry.
     
    , Jun 20, 2006
    #1
    1. Advertising

  2. Ian Collins Guest

    wrote:
    > Hi,
    >
    > I have a function which compares two unsigned ints and returns their
    > difference in order to establish which is the greater of the two.
    >
    > int Compare(unsigned int time_left, unsigned int time_right)
    > {
    > return (time_left - time_right);
    > }
    >
    > usage -
    >
    > if( Compare(time_left, time_right) > 0)
    > // the time has come.
    >
    > The problem is that when time_left is 5 and time_right is 10, I get -5,
    > but if time_left is 5 and time_right is 0xc0000005 (a number greater
    > than 5) I get a positive value when I wish to get a negitive one.
    >
    > I understand why I get this positive value - because the negaitve bit
    > is set in time_right, but how can I change my code so that I get the
    > desired results.
    >


    If the exact difference doesn't matter;

    return (time_left > time_right);

    or

    return ((time_left > time_right) ? 1 : 0);

    --
    Ian Collins.
     
    Ian Collins, Jun 20, 2006
    #2
    1. Advertising

  3. wrote:
    > Hi,
    >
    > I have a function which compares two unsigned ints and returns their
    > difference in order to establish which is the greater of the two.


    You can't subtract two unsigned ints and yield a negative number.

    > int Compare(unsigned int time_left, unsigned int time_right)
    > {
    > return (time_left - time_right);
    > }
    >
    > usage -
    >
    > if( Compare(time_left, time_right) > 0)
    > // the time has come.
    >
    > The problem is that when time_left is 5 and time_right is 10, I get -5,
    > but if time_left is 5 and time_right is 0xc0000005 (a number greater
    > than 5) I get a positive value when I wish to get a negitive one.


    Try...

    if (time_left < time_right) return -1;
    if (time_left > time_right) return +1;
    return 0;

    Or...

    return (time_left < time_right) ? -1 : (time_left > time_right);

    Or...

    return (time_left > time_right) - (time_left < time_right);

    >
    > I understand why I get this positive value - because the negaitve bit
    > is set in time_right, ...


    No, time_right is an unsigned int. There is _no_ negative (sign) bit.

    The problem is that arithmetic on unsigned ints is performed
    modulo one more than UINT_MAX.

    --
    Peter
     
    Peter Nilsson, Jun 20, 2006
    #3
  4. Nelu Guest

    writes:

    > Hi,
    >
    > I have a function which compares two unsigned ints and returns their
    > difference in order to establish which is the greater of the two.
    >
    > int Compare(unsigned int time_left, unsigned int time_right)
    > {
    > return (time_left - time_right);
    > }
    >
    > usage -
    >
    > if( Compare(time_left, time_right) > 0)
    > // the time has come.
    >
    > The problem is that when time_left is 5 and time_right is 10, I get -5,
    > but if time_left is 5 and time_right is 0xc0000005 (a number greater
    > than 5) I get a positive value when I wish to get a negitive one.
    >
    > I understand why I get this positive value - because the negaitve bit
    > is set in time_right, but how can I change my code so that I get the
    > desired results.
    >


    It doesn't matter what you set. It's supposed to be an unsigned int so
    it gets promoted to something higher than int (assuming that int has 4
    bytes) to be able to store the positive value. They probably get
    promoted to long so you have a difference between two long
    arguments. But, you are returning int even if the unsigned value
    doesn't fit in an int.

    --
    Ioan - Ciprian Tandau
    tandau _at_ freeshell _dot_ org (hope it's not too late)
    (... and that it still works...)
     
    Nelu, Jun 20, 2006
    #4
  5. Eric Sosman Guest

    Nelu wrote:

    > writes:
    >
    >
    >>Hi,
    >>
    >>I have a function which compares two unsigned ints and returns their
    >>difference in order to establish which is the greater of the two.
    >>
    >>int Compare(unsigned int time_left, unsigned int time_right)
    >>{
    >> return (time_left - time_right);
    >>}
    >>
    >>usage -
    >>
    >>if( Compare(time_left, time_right) > 0)
    >> // the time has come.
    >>
    >>The problem is that when time_left is 5 and time_right is 10, I get -5,
    >>but if time_left is 5 and time_right is 0xc0000005 (a number greater
    >>than 5) I get a positive value when I wish to get a negitive one.
    >>
    >>I understand why I get this positive value - because the negaitve bit
    >>is set in time_right, but how can I change my code so that I get the
    >>desired results.
    >>

    >
    >
    > It doesn't matter what you set. It's supposed to be an unsigned int so
    > it gets promoted to something higher than int (assuming that int has 4
    > bytes) to be able to store the positive value. They probably get
    > promoted to long so you have a difference between two long
    > arguments. But, you are returning int even if the unsigned value
    > doesn't fit in an int.


    You were doing fine until the second sentence, which is
    wrong and misleading: Wrong because unsigned int is not "promotable"
    at all, and misleading because the four-byte int is a red herring
    that has nothing to do with anything. The third sentence, since
    its premise is a falsehood, is simply meaningless.

    Your final sentence, though, correctly identifies the crux
    of the problem. Others have offered solutions.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jun 20, 2006
    #5
  6. pete Guest

    Nelu wrote:
    >
    > writes:
    >
    > > Hi,
    > >
    > > I have a function which compares two unsigned ints and returns their
    > > difference in order to establish which is the greater of the two.
    > >
    > > int Compare(unsigned int time_left, unsigned int time_right)
    > > {
    > > return (time_left - time_right);
    > > }
    > >
    > > usage -
    > >
    > > if( Compare(time_left, time_right) > 0)
    > > // the time has come.
    > >
    > > The problem is that when time_left is 5 and time_right is 10,
    > > I get -5,
    > > but if time_left is 5 and time_right is 0xc0000005 (a number greater
    > > than 5) I get a positive value when I wish to get a negitive one.
    > >
    > > I understand why I get this positive value
    > > - because the negaitve bit
    > > is set in time_right, but how can I change my code so that I get the
    > > desired results.
    > >

    >
    > It doesn't matter what you set. It's supposed to be an unsigned int so
    > it gets promoted to something higher than int (assuming that int has 4
    > bytes) to be able to store the positive value. They probably get
    > promoted to long so you have a difference between two long
    > arguments. But, you are returning int even if the unsigned value
    > doesn't fit in an int.


    I don't understand what you mean.
    There's nothing getting promoted in the shown code.
    The type of (time_left - time_right) is unsigned int.
    The only conversion in the shown code
    is that the return value of the function,
    is (time_left - time_right) converted to type int,
    which is implementation defined
    if (time_left - time_right) is greater than INT_MAX.

    --
    pete
     
    pete, Jun 20, 2006
    #6
  7. Jack Klein Guest

    On 19 Jun 2006 18:06:25 -0700, wrote in comp.lang.c:

    > Hi,
    >
    > I have a function which compares two unsigned ints and returns their
    > difference in order to establish which is the greater of the two.
    >
    > int Compare(unsigned int time_left, unsigned int time_right)
    > {
    > return (time_left - time_right);
    > }
    >
    > usage -
    >
    > if( Compare(time_left, time_right) > 0)
    > // the time has come.
    >
    > The problem is that when time_left is 5 and time_right is 10, I get -5,
    > but if time_left is 5 and time_right is 0xc0000005 (a number greater
    > than 5) I get a positive value when I wish to get a negitive one.
    >
    > I understand why I get this positive value - because the negaitve bit
    > is set in time_right, but how can I change my code so that I get the
    > desired results.
    >
    > Thanks for your help,


    What happens if the difference is has greater magnitude that a signed
    int can hold? If one of the values is UINT_MAX and the other is 0,
    the difference between them is either positive or negative UINT_MAX,
    and that won't fit in a signed int on any platform you are ever likely
    to see in your career.

    Still assuming it fits (untested):

    int Compare(unsigned int time_left, unsigned int time_right)
    {
    int result;

    if (time_left >= time_right)
    {
    result = time_left - time_right;
    }
    else
    {
    result = -(int)(time_right - time_left);
    }
    return result;
    }

    --
    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.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jun 20, 2006
    #7
  8. Nelu Guest

    Eric Sosman <> writes:

    > Nelu wrote:
    >
    > > writes:
    > >
    > >>Hi,
    > >>
    > >>I have a function which compares two unsigned ints and returns their
    > >>difference in order to establish which is the greater of the two.
    > >>
    > >>int Compare(unsigned int time_left, unsigned int time_right)
    > >>{
    > >> return (time_left - time_right);
    > >>}
    > >>
    > >>usage -
    > >>
    > >>if( Compare(time_left, time_right) > 0)
    > >> // the time has come.
    > >>
    > >>The problem is that when time_left is 5 and time_right is 10, I get -5,
    > >>but if time_left is 5 and time_right is 0xc0000005 (a number greater
    > >>than 5) I get a positive value when I wish to get a negitive one.
    > >>
    > >>I understand why I get this positive value - because the negaitve bit
    > >>is set in time_right, but how can I change my code so that I get the
    > >>desired results.
    > >>

    > > It doesn't matter what you set. It's supposed to be an unsigned int
    > > so
    > > it gets promoted to something higher than int (assuming that int has 4
    > > bytes) to be able to store the positive value. They probably get
    > > promoted to long so you have a difference between two long
    > > arguments. But, you are returning int even if the unsigned value
    > > doesn't fit in an int.

    >
    > You were doing fine until the second sentence, which is
    > wrong and misleading: Wrong because unsigned int is not "promotable"
    > at all,
    > and misleading because the four-byte int is a red herring
    > that has nothing to do with anything. The third sentence, since


    The 4 byte thing was a reference to the hex value and the explanation
    the OP provided.
    I got the promotion thing wrong. I have re-read the standard. I
    should've taken another look before posting. Sorry about that.

    > its premise is a falsehood, is simply meaningless.

    Yes it is.

    --
    Ioan - Ciprian Tandau
    tandau _at_ freeshell _dot_ org (hope it's not too late)
    (... and that it still works...)
     
    Nelu, Jun 20, 2006
    #8
  9. CBFalconer Guest

    wrote:
    >
    > I have a function which compares two unsigned ints and returns
    > their difference in order to establish which is the greater of
    > the two.
    >
    > int Compare(unsigned int time_left, unsigned int time_right)
    > {
    > return (time_left - time_right);
    > }
    >
    > usage -
    >
    > if( Compare(time_left, time_right) > 0)
    > // the time has come.
    >
    > The problem is that when time_left is 5 and time_right is 10, I
    > get -5, but if time_left is 5 and time_right is 0xc0000005 (a
    > number greater than 5) I get a positive value when I wish to get
    > a negitive one.
    >
    > I understand why I get this positive value - because the negaitve
    > bit is set in time_right, but how can I change my code so that I
    > get the desired results.


    By avoiding overflows and undefined behaviour. Forget 'sign bits'.

    int compare(unsigned int left, unsigned int right)
    {
    return (left < right) - (left > right);
    }

    --
    "I don't know where bin Laden is. I have no idea and really
    don't care. It's not that important." - G.W. Bush, 2002-03-13
    "No, we've had no evidence that Saddam Hussein was involved
    with September the 11th." - George Walker Bush 2003-09-17
     
    CBFalconer, Jun 20, 2006
    #9
  10. Eric Sosman wrote:
    > Nelu wrote:
    > > writes:
    > > > int Compare(unsigned int time_left, unsigned int time_right)
    > > > {
    > > > return (time_left - time_right);
    > > > }

    > >
    > > ...
    > > It doesn't matter what you set. It's supposed to be an unsigned int so
    > > it gets promoted to something higher than int (assuming that int has 4
    > > bytes) to be able to store the positive value. They probably get
    > > promoted to long so you have a difference between two long
    > > arguments. But, you are returning int even if the unsigned value
    > > doesn't fit in an int.

    >
    > You were doing fine until the second sentence, which is
    > wrong and misleading: Wrong because unsigned int is not "promotable"
    > at all, ...


    To clarify, although not subject to integral promotion, an unsigned int
    operand is potentially subject to arithmetic conversion. However, in
    the
    case at hand, arithmetic conversion is not applicable since both
    operands
    are unsigned int.

    --
    Peter
     
    Peter Nilsson, Jun 20, 2006
    #10
  11. Eric Sosman Guest

    CBFalconer wrote:

    > wrote:
    >
    >>I have a function which compares two unsigned ints and returns
    >>their difference in order to establish which is the greater of
    >>the two.
    >>
    >>int Compare(unsigned int time_left, unsigned int time_right)
    >>{
    >> return (time_left - time_right);
    >>}
    >>
    >>usage -
    >>
    >>if( Compare(time_left, time_right) > 0)
    >> // the time has come.
    >>
    >>The problem is that when time_left is 5 and time_right is 10, I
    >>get -5, but if time_left is 5 and time_right is 0xc0000005 (a
    >>number greater than 5) I get a positive value when I wish to get
    >>a negitive one.
    >>
    >>I understand why I get this positive value - because the negaitve
    >>bit is set in time_right, but how can I change my code so that I
    >>get the desired results.

    >
    >
    > By avoiding overflows and undefined behaviour. Forget 'sign bits'.
    >
    > int compare(unsigned int left, unsigned int right)
    > {
    > return (left < right) - (left > right);
    > }


    Aside: I think this is backwards from the O.P.'s intent.
    Either exchange the operands of `-' or interchange `<' and `>'.
    (Suggestion: Don't make *both* changes. ;-)

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jun 20, 2006
    #11
    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. Replies:
    3
    Views:
    607
    Mark P
    Apr 3, 2005
  2. Skybuck Flying

    ints ints ints and ints

    Skybuck Flying, Jul 8, 2004, in forum: C Programming
    Replies:
    24
    Views:
    870
    Jack Klein
    Jul 10, 2004
  3. Subtracting unsigned entities

    , May 12, 2008, in forum: C Programming
    Replies:
    9
    Views:
    408
    Harald van Dijk
    May 13, 2008
  4. Thomas Richter

    Re: Subtracting two big unsigned numbers

    Thomas Richter, Jun 9, 2011, in forum: C Programming
    Replies:
    2
    Views:
    449
    James Kuyper
    Jun 11, 2011
  5. Keith Thompson

    Re: Subtracting two big unsigned numbers

    Keith Thompson, Jun 9, 2011, in forum: C Programming
    Replies:
    4
    Views:
    1,367
    Keith Thompson
    Jun 15, 2011
Loading...

Share This Page