|
-
May 7th, 2004, 11:19 AM
#1
Unsigned numbers: am I correct in my understanding?
Code Gurus,
I ran into a bug which was at first very hard to detect.
I figured it out later on but I want to make sure my assumption is correct about this problem.
Let's say we have an unsigned number
unsigned int x = 10;
int y = 20;
Let's say we have the code:
if( (x - y) < 0 )
{
// x - y is less than 0
}else
{
// x - y is greater than 0
}
This code will never enter into the if-block statement.
Why?
My assumption is that the terms (x - y) as a whole term is
evaluating as an unsigned number thus the value is greater than zero.
Am I correct in my understanding here?
What is going on?
Thanks.
-
May 7th, 2004, 05:58 PM
#2
you are correct. unsigned has precedence over signed.
if you need to use signed and unsigned with the same expression, then you should cast the unsigned into signed:
unsigned int uInt = ...
int sInt = ...
if( sInt > (int)uInt )
...
**** **** **** **** **/**
-
May 8th, 2004, 10:10 AM
#3
You could also reverse that:
if( (y-x) >= 0 ) ...
-
May 8th, 2004, 12:18 PM
#4
mwilliamson,
if( (y-x) >= 0 )
wont work since the expressions (y-x) and (x-y) are unsigned the result is always true even if y is negative.
Regards,
Guy
**** **** **** **** **/**
-
May 8th, 2004, 06:14 PM
#5
Guysl is correct. His example shows casting in C. If you're using C++, you'll want to use static_cast<T> (expr)
-
May 10th, 2004, 09:13 AM
#6
Thanks guys! Appreciate it.
-
May 10th, 2004, 11:22 AM
#7
I can't find the reference, and I can't remember if it was Stroustrup, Meyers or Sutter who said it, but I remember reading an article about unsigned within the last year or so. It contained a lot of supporting reasoning, but basically boiled down to: "don't use unsigned in arithmetic situations". Don't even use unsigned to indicate the your data is meant to be zero-positive. Reserve unsigned for things like bitmasks, where you are doing bitwise operations, not arithmetic.
Code:
void foo(unsigned int x);
int main()
{
foo(-1);
}
void foo(unsigned int x)
{
// Data validation - how?
}
Compare:
Code:
void foo(int x);
int main()
{
foo(-1);
}
void foo(int x)
{
if (x < 0)
throw bad_argument();
else
{
// ...
}
}
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
May 10th, 2004, 08:45 PM
#8
If I remember correctly, the following is one of the example used to explain why we should avoid unsigned.
Code:
int main(void)
{
unsigned i;
for (i=10; i >= 0; i--)
{
printf(“i is %u\n”, i);
}
return 0;
}
The for-loop will not stop since the unsigned i will never be smaller than 0. Whenever i becomes zero, the next decrement causes it to become the largest unsigned value due to over/underflow.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|