Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Subtracting unsigned ints

Reply
Thread Tools

Subtracting unsigned ints

 
 
bg_ie@yahoo.com
Guest
Posts: n/a
 
      06-20-2006
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.

 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      06-20-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) 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.
 
Reply With Quote
 
 
 
 
Peter Nilsson
Guest
Posts: n/a
 
      06-20-2006
(E-Mail Removed) 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

 
Reply With Quote
 
Nelu
Guest
Posts: n/a
 
      06-20-2006
(E-Mail Removed) 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...)
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      06-20-2006
Nelu wrote:

> (E-Mail Removed) 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
(E-Mail Removed)lid
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      06-20-2006
Nelu wrote:
>
> (E-Mail Removed) 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
 
Reply With Quote
 
Jack Klein
Guest
Posts: n/a
 
      06-20-2006
On 19 Jun 2006 18:06:25 -0700, (E-Mail Removed) 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/~a...FAQ-acllc.html
 
Reply With Quote
 
Nelu
Guest
Posts: n/a
 
      06-20-2006
Eric Sosman <(E-Mail Removed)> writes:

> Nelu wrote:
>
> > (E-Mail Removed) 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...)
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      06-20-2006
(E-Mail Removed) 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


 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      06-20-2006
Eric Sosman wrote:
> Nelu wrote:
> > (E-Mail Removed) 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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Subtracting two big unsigned numbers Thomas Richter C Programming 2 06-11-2011 03:02 AM
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
Subtracting unsigned entities fred.l.kleinschmidt@boeing.com C Programming 9 05-13-2008 09:16 PM
Iterator Question for map of ints to set of ints uclamathguy@gmail.com C++ 3 04-03-2005 03:26 AM
ints ints ints and ints Skybuck Flying C Programming 24 07-10-2004 04:48 AM



Advertisments