efficiency concern: when to really use unsigned ints and when not to

Discussion in 'C Programming' started by Neil Zanella, Feb 5, 2004.

1. Neil ZanellaGuest

Hello,

Often I happen to be dealing with nonnegative integers and since I know I won't
need negative numbers here I declare them as unsigned simply to make the program
somewhat clearer. Effectively, though, signed integers would often work too since
unless I am doing some modular arithmetic modulo the word length then I almost
never need to use the high bit since the integers I deal with are usually not
that large, and I would assume this is true of most programs in general.

So, the question is, when you know an integer is not going to be negative, is that
good enough reason to declare it as unsigned, or does doing so somewhat slow down
the computer (e.g. are signed addition, subtraction, etc... somewhat faster and
why would that be so?)?

Thanks,

Neil

Neil Zanella, Feb 5, 2004

2. Richard HeathfieldGuest

Neil Zanella wrote:

> Hello,
>
> Often I happen to be dealing with nonnegative integers and since I know I
> won't need negative numbers here I declare them as unsigned simply to make
> the program somewhat clearer.

So do I.

> Effectively, though, signed integers would
> often work too since unless I am doing some modular arithmetic modulo the
> word length then I almost never need to use the high bit since the
> integers I deal with are usually not that large, and I would assume this
> is true of most programs in general.

Well, if your modulus happens to be 2 to the N, where N is the number of
value bits in the unsigned integer type, you're in luck.

But I presume you're talking about, say, day of week (modulo 7), month of
year (modulo 12), or perhaps (integral) angle in degrees (modulo 360). That
/sort/ of thing.

> So, the question is, when you know an integer is not going to be negative,
> is that good enough reason to declare it as unsigned,

IMHO, yes.

> or does doing so
> somewhat slow down the computer (e.g. are signed addition, subtraction,
> etc... somewhat faster and why would that be so?)?

The Standard doesn't require unsigned integer types to go slower than signed
integer types.

If you are sure you'll never overflow the maximum value for the type, feel
free to use signed if you wish. I prefer to use unsigneds.

--
Richard Heathfield :
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

Richard Heathfield, Feb 5, 2004

3. Mark A. OdellGuest

(Neil Zanella) wrote in
news::

> Often I happen to be dealing with nonnegative integers and since I know
> I won't need negative numbers here I declare them as unsigned simply to
> make the program somewhat clearer. Effectively, though, signed integers
> would often work too since unless I am doing some modular arithmetic
> modulo the word length then I almost never need to use the high bit
> since the integers I deal with are usually not that large, and I would
> assume this is true of most programs in general.
>
> So, the question is, when you know an integer is not going to be
> negative, is that good enough reason to declare it as unsigned, or does
> doing so somewhat slow down the computer (e.g. are signed addition,
> subtraction, etc... somewhat faster and why would that be so?)?

On small micros without sign-support hardware signed maybe slower, e.g.
the venerable 8051. However, unless you need instruction level determinism
I wouldn't worry about it. Make the vars. unsigned when the value is not
negative. For example, why would you ever need to express someone's age in
years as a signed value? Since we know better than to mix control with
data we wouldn't use a negative value for an error so I'd certainly expect
to see age declared as:

unsigned int ageInYears;

or

unsigned char ageInYears;

--
- Mark ->
--

Mark A. Odell, Feb 5, 2004
4. Christian BauGuest

In article <>,
(Neil Zanella) wrote:

> Hello,
>
> Often I happen to be dealing with nonnegative integers and since I know I
> won't
> need negative numbers here I declare them as unsigned simply to make the
> program
> somewhat clearer. Effectively, though, signed integers would often work too
> since
> unless I am doing some modular arithmetic modulo the word length then I
> almost
> never need to use the high bit since the integers I deal with are usually not
> that large, and I would assume this is true of most programs in general.
>
> So, the question is, when you know an integer is not going to be negative, is
> that
> good enough reason to declare it as unsigned, or does doing so somewhat slow
> down
> the computer (e.g. are signed addition, subtraction, etc... somewhat faster
> and
> why would that be so?)?

For signed integers, the C operators +, -, * produce exactly the same
results as the mathematical operators (as long as the results are not
too large). For unsigned integers, the C operators do some pretty weird
things. A trivial example: For which numbers is

x >= y - 1

true if x and y are both signed, both unsigned, one signed and the other
unsigned? For signed numbers, you are quite safe. Both unsigned, and
there is a strange special case for y = 0. One signed and the other
unsigned, and you have to study the C Standard.

It seems what you have are "positive" numbers. "unsigned" is something
completely different; unsigned numbers can behave in completely
unexpected ways. x - 1 is not one less than x in very common cases.

(And some people will be in for some nasty surprises if they switch to a
compiler where unsigned int and unsigned long have different sizes. )

Christian Bau, Feb 5, 2004
5. Keith ThompsonGuest

(Neil Zanella) writes:
> Often I happen to be dealing with nonnegative integers and since I
> know I won't need negative numbers here I declare them as unsigned
> simply to make the program somewhat clearer. Effectively, though,
> signed integers would often work too since unless I am doing some
> modular arithmetic modulo the word length then I almost never need
> to use the high bit since the integers I deal with are usually not
> that large, and I would assume this is true of most programs in
> general.
>
> So, the question is, when you know an integer is not going to be
> negative, is that good enough reason to declare it as unsigned, or
> does doing so somewhat slow down the computer (e.g. are signed
> addition, subtraction, etc... somewhat faster and why would that be
> so?)?

There are some risks in using unsigned types. Consider:

int i;
for (i = 9; i >= 0; i --) { printf("%d\n", i); }

vs.

unsigned int u;
for (u = 9; u >= 0; u --) { printf("%u\n", u); }

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"

Keith Thompson, Feb 6, 2004
6. Jack KleinGuest

On 5 Feb 2004 22:20:43 GMT, "Mark A. Odell" <>
wrote in comp.lang.c:

> (Neil Zanella) wrote in
> news::
>
> > Often I happen to be dealing with nonnegative integers and since I know
> > I won't need negative numbers here I declare them as unsigned simply to
> > make the program somewhat clearer. Effectively, though, signed integers
> > would often work too since unless I am doing some modular arithmetic
> > modulo the word length then I almost never need to use the high bit
> > since the integers I deal with are usually not that large, and I would
> > assume this is true of most programs in general.
> >
> > So, the question is, when you know an integer is not going to be
> > negative, is that good enough reason to declare it as unsigned, or does
> > doing so somewhat slow down the computer (e.g. are signed addition,
> > subtraction, etc... somewhat faster and why would that be so?)?

>
> On small micros without sign-support hardware signed maybe slower, e.g.
> the venerable 8051

[snip]

<somewhat off topic>
I beg your pardon, but an 8051 has a carry flag and can performed
signed arithmetic with the same speed as unsigned arithmetic.

There are a lot of reasons to look down one's nose and the brain-dead
little work-horse, but this is not one of them.
</somewhat off topic>

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
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, Feb 6, 2004
7. Jack KleinGuest

On 5 Feb 2004 13:18:31 -0800, (Neil Zanella) wrote
in comp.lang.c:

> Hello,
>
> Often I happen to be dealing with nonnegative integers and since I know I won't
> need negative numbers here I declare them as unsigned simply to make the program
> somewhat clearer. Effectively, though, signed integers would often work too since
> unless I am doing some modular arithmetic modulo the word length then I almost
> never need to use the high bit since the integers I deal with are usually not
> that large, and I would assume this is true of most programs in general.
>
> So, the question is, when you know an integer is not going to be negative, is that
> good enough reason to declare it as unsigned, or does doing so somewhat slow down
> the computer (e.g. are signed addition, subtraction, etc... somewhat faster and
> why would that be so?)?
>
> Thanks,
>
> Neil

Speed or efficiency of operation is no different between pure signed
or unsigned types on any architecture developed in the last quarter
century at least.

There are pros and cons to using unsigned types.

One of the biggest pros is simpler range checking in functions.
Suppose for example that you have a function that can be properly
called with a value between 0 and 10, and it is the function's job to
validate the argument and return an error code if it is out of range.
Now look at the two functions below:

int s_func(signed int x)
{
if ((x >= 0) && (x <= 10))
{
/* do stuff */
return OK;
}
else
{
return ERROR;
}
}

Now the unsigned version, the checking is simpler:

int u_func(unsigned int x)
{
if (x <= 10)
--------

The biggest con to using unsigned is that you have to know what can
happen when mixing with signed or you can be unpleasantly surprised.

unsigned int x = 12;

if (x > -1)
{
puts("Yippee!");
}
else
{
puts("Ouch!");
}

The code above will output "Ouch!".

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
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, Feb 6, 2004
8. Martin DickoppGuest

Re: efficiency concern: when to really use unsigned ints and whennot to

Christian Bau <> writes:

> For signed integers, the C operators +, -, * produce exactly the same
> results as the mathematical operators (as long as the results are not
> too large).

ITYM as long as the absolute values of the results are not too large.

> For unsigned integers, the C operators do some pretty weird
> things. A trivial example: For which numbers is
>
> x >= y - 1
>
> true if x and y are both signed, both unsigned, one signed and the other
> unsigned? For signed numbers, you are quite safe. Both unsigned, and
> there is a strange special case for y = 0.

For signed ints, there is a strange special case for y = INT_MIN. With
unsigned integers, you have well-defined over/underflow semantics at
least, but as long as you stay within the range of the type, you are
safe with both signed and unsigned integers.

Martin

Martin Dickopp, Feb 6, 2004
9. Martin DickoppGuest

Re: efficiency concern: when to really use unsigned ints and whennot to

Keith Thompson <> writes:

> There are some risks in using unsigned types. Consider:
>
> int i;
> for (i = 9; i >= 0; i --) { printf("%d\n", i); }
>
> vs.
>
> unsigned int u;
> for (u = 9; u >= 0; u --) { printf("%u\n", u); }

Some compilers can even warn you of comparisons which are always true.
The latter case can be rewritten as, for example,

unsigned int u;
for (u = 10; u-- > 0 { printf("%u\n", u); }

which uses unsigned integers and has the intended effect.

Martin

Martin Dickopp, Feb 6, 2004
10. Christian BauGuest

In article <bvvcvd\$lt8\$05\$-online.com>,
Martin Dickopp <> wrote:

> Christian Bau <> writes:
>
> > For signed integers, the C operators +, -, * produce exactly the same
> > results as the mathematical operators (as long as the results are not
> > too large).

>
> ITYM as long as the absolute values of the results are not too large.
>
> > For unsigned integers, the C operators do some pretty weird
> > things. A trivial example: For which numbers is
> >
> > x >= y - 1
> >
> > true if x and y are both signed, both unsigned, one signed and the other
> > unsigned? For signed numbers, you are quite safe. Both unsigned, and
> > there is a strange special case for y = 0.

>
> For signed ints, there is a strange special case for y = INT_MIN. With
> unsigned integers, you have well-defined over/underflow semantics at
> least, but as long as you stay within the range of the type, you are
> safe with both signed and unsigned integers.

Which case happens more often, INT_MIN or 0?

Christian Bau, Feb 6, 2004
11. Christian BauGuest

In article <bvvdbj\$lt8\$05\$-online.com>,
Martin Dickopp <> wrote:

> Some compilers can even warn you of comparisons which are always true.
> The latter case can be rewritten as, for example,
>
> unsigned int u;
> for (u = 10; u-- > 0 { printf("%u\n", u); }
>
> which uses unsigned integers and has the intended effect.

Yes, I have the pleasure to use one f***ing compiler that doesn't let me
write

if (x >= 0 && x <= 10)

if x is an unsigned value without giving a warning.

Christian Bau, Feb 6, 2004
12. Martin DickoppGuest

Re: efficiency concern: when to really use unsigned ints and whennot to

Christian Bau <> writes:

> In article <bvvcvd\$lt8\$05\$-online.com>,
> Martin Dickopp <> wrote:
>
>> Christian Bau <> writes:
>>
>> > For signed integers, the C operators +, -, * produce exactly the same
>> > results as the mathematical operators (as long as the results are not
>> > too large).

>>
>> ITYM as long as the absolute values of the results are not too large.
>>
>> > For unsigned integers, the C operators do some pretty weird
>> > things. A trivial example: For which numbers is
>> >
>> > x >= y - 1
>> >
>> > true if x and y are both signed, both unsigned, one signed and the other
>> > unsigned? For signed numbers, you are quite safe. Both unsigned, and
>> > there is a strange special case for y = 0.

>>
>> For signed ints, there is a strange special case for y = INT_MIN. With
>> unsigned integers, you have well-defined over/underflow semantics at
>> least, but as long as you stay within the range of the type, you are
>> safe with both signed and unsigned integers.

>
> Which case happens more often, INT_MIN or 0?

I fully agree with you that if there is a risk of "underflowing" an
unsigned integer (and the wrap-around behavior is not deliberately
wanted), a signed integer type should be used. However, IMHO unsigned
integers should be used when there's no such risk.

Perhaps the programmer has to think more carefully when using unsigned
integers, and yet more carefully when mixing them with signed integers.
I consider this a good thing.

When I was just beginning to learn programming and C, I did in fact
write a `while (n >= 0)' loop, where `n' was an unsigned integer (and
the compiler I used at that time did /not/ warn about it). When I saw
my mistake, I didn't conclude that I should just avoid unsigned integers
(either in this special case or in general), but that I should think
again what I'm doing.

Martin

Martin Dickopp, Feb 6, 2004
13. Martin DickoppGuest

Re: efficiency concern: when to really use unsigned ints and whennot to

Christian Bau <> writes:

> In article <bvvdbj\$lt8\$05\$-online.com>,
> Martin Dickopp <> wrote:
>
>> Some compilers can even warn you of comparisons which are always true.
>> The latter case can be rewritten as, for example,
>>
>> unsigned int u;
>> for (u = 10; u-- > 0 { printf("%u\n", u); }
>>
>> which uses unsigned integers and has the intended effect.

>
> Yes, I have the pleasure to use one f***ing compiler that doesn't let me
> write
>
> if (x >= 0 && x <= 10)
>
> if x is an unsigned value without giving a warning.

Well, I have the pleasure to use a fine compiler that has a command line
option to switch the warning on or off.

Martin

Martin Dickopp, Feb 6, 2004
14. peteGuest

Christian Bau wrote:
>
> In article <bvvdbj\$lt8\$05\$-online.com>,
> Martin Dickopp <> wrote:
>
> > Some compilers can even warn you of comparisons
> > which are always true.
> > The latter case can be rewritten as, for example,
> >
> > unsigned int u;
> > for (u = 10; u-- > 0 { printf("%u\n", u); }
> >
> > which uses unsigned integers and has the intended effect.

>
> Yes, I have the pleasure to use one
> f***ing compiler that doesn't let me write
>
> if (x >= 0 && x <= 10)
>
> if x is an unsigned value without giving a warning.

I don't understand the reason for the deletable expletive.
The warning was good and proper and useful and caused you to
change your meaningless code, right ?

--
pete

pete, Feb 6, 2004
15. Mark A. OdellGuest

Jack Klein <> wrote in
news::

> <somewhat off topic>
> I beg your pardon, but an 8051 has a carry flag and can performed
> signed arithmetic with the same speed as unsigned arithmetic.
>
> There are a lot of reasons to look down one's nose and the brain-dead
> little work-horse, but this is not one of them.

True it has a carry flag and that means extra instructions to check it
when using signed integers. When using unsigned integers, no assy. is
produced to check the carry flag.

> </somewhat off topic>

--
- Mark ->
--

Mark A. Odell, Feb 6, 2004
16. nrkGuest

Christian Bau wrote:

> In article <bvvdbj\$lt8\$05\$-online.com>,
> Martin Dickopp <> wrote:
>
>> Some compilers can even warn you of comparisons which are always true.
>> The latter case can be rewritten as, for example,
>>
>> unsigned int u;
>> for (u = 10; u-- > 0 { printf("%u\n", u); }
>>
>> which uses unsigned integers and has the intended effect.

>
> Yes, I have the pleasure to use one f***ing compiler that doesn't let me
> write
>
> if (x >= 0 && x <= 10)
>
> if x is an unsigned value without giving a warning.

Ok, you've lost me. If x is unsigned why would you ever want to check a
tautology x >= 0? I think your compiler is doing a fine job, and its you
who's effing up

-nrk.
--
Remove devnull for email

nrk, Feb 6, 2004
17. Dan PopGuest

In <> (Neil Zanella) writes:

>Often I happen to be dealing with nonnegative integers and since I know I won't
>need negative numbers here I declare them as unsigned simply to make the program
>somewhat clearer. Effectively, though, signed integers would often work too since
>unless I am doing some modular arithmetic modulo the word length then I almost
>never need to use the high bit since the integers I deal with are usually not
>that large, and I would assume this is true of most programs in general.

Signed integers and unsigned integers are fairly different beasts,
intended for different purposes. Avoid unsigned integers unless you need
their special semantics (or the additional range), even if you're only
manipulating positive values. After all, the prototype of main() isn't

int main(unsigned argc, char **argv);

despite the fact that argc is not supposed to have negative values.

If it's intended for usual arithmetic operations, use signed integer.
If it's intended for bit manipulation operations and/or modulo arithmetic,
use unsigned integer.

Avoid as much as possible mixing the two flavours in the same
expression, because very nasty bugs may arise.

The fact that size_t is unsigned is a real pain in the ass, because this
type is seldom used in a genuine unsigned context. It should have been
signed, for the same reason that argc is signed.

>So, the question is, when you know an integer is not going to be negative, is that
>good enough reason to declare it as unsigned,

Nope.

>or does doing so somewhat slow down
>the computer (e.g. are signed addition, subtraction, etc... somewhat faster and
>why would that be so?)?

Speed is not a concern. On two's complement architectures, the two are
usually handled identically. It's the intended purpose of the variable
that dictates the choice (again, unless you need the extra range provided
by the unsigned flavour, but this doesn't seem to be the case).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email:

Dan Pop, Feb 6, 2004
18. Dan PopGuest

In <Xns94875AE8F4267CopyrightMarkOdell@130.133.1.4> "Mark A. Odell" <> writes:

>Jack Klein <> wrote in
>news::
>
>> <somewhat off topic>
>> I beg your pardon, but an 8051 has a carry flag and can performed
>> signed arithmetic with the same speed as unsigned arithmetic.
>>
>> There are a lot of reasons to look down one's nose and the brain-dead
>> little work-horse, but this is not one of them.

>
>True it has a carry flag and that means extra instructions to check it
>when using signed integers.

Why do you need to check it when using signed integers? The carry flag
*must* be taken into account when doing both signed and unsigned
arithmetic on multi-byte operands, but this is usually achieved by using
the "add with carry" instruction, not by checking the carry flag.

>When using unsigned integers, no assy. is
>produced to check the carry flag.

And what kind of assembly is generated to check the carry flag when using
signed integers? Do the 8051 compilers bother to check for signed
integer overflow? I'd be really surprised...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email:

Dan Pop, Feb 6, 2004
19. Christian BauGuest

In article <>,
pete <> wrote:

> Christian Bau wrote:
> >
> > In article <bvvdbj\$lt8\$05\$-online.com>,
> > Martin Dickopp <> wrote:
> >
> > > Some compilers can even warn you of comparisons
> > > which are always true.
> > > The latter case can be rewritten as, for example,
> > >
> > > unsigned int u;
> > > for (u = 10; u-- > 0 { printf("%u\n", u); }
> > >
> > > which uses unsigned integers and has the intended effect.

> >
> > Yes, I have the pleasure to use one
> > f***ing compiler that doesn't let me write
> >
> > if (x >= 0 && x <= 10)
> >
> > if x is an unsigned value without giving a warning.

>
> I don't understand the reason for the deletable expletive.
> The warning was good and proper and useful and caused you to
> change your meaningless code, right ?

Completely brainlessly wrong. The code checked that the value of a
variable was in a certain constant range. If I want to know whether a
value x is in a range from a to b then I write "if (x >= a && x <= b)".
It is absolutely idiotic to have a special case for a = 0.

Changing the code would have created maintenance problems: If a variable
can hold values lets say from 0 to 100, then any integer type whether
signed or unsigned can hold all the values. However, changing the type
from unsigned to signed makes the code incorrect if the test x >= 0 is
missing.

Christian Bau, Feb 6, 2004
20. Christian BauGuest

In article <BAQUb.15116\$>,
nrk <> wrote:

> Christian Bau wrote:
>
> > In article <bvvdbj\$lt8\$05\$-online.com>,
> > Martin Dickopp <> wrote:
> >
> >> Some compilers can even warn you of comparisons which are always true.
> >> The latter case can be rewritten as, for example,
> >>
> >> unsigned int u;
> >> for (u = 10; u-- > 0 { printf("%u\n", u); }
> >>
> >> which uses unsigned integers and has the intended effect.

> >
> > Yes, I have the pleasure to use one f***ing compiler that doesn't let me
> > write
> >
> > if (x >= 0 && x <= 10)
> >
> > if x is an unsigned value without giving a warning.

>
> Ok, you've lost me. If x is unsigned why would you ever want to check a
> tautology x >= 0? I think your compiler is doing a fine job, and its you
> who's effing up

When checking whether "minimum value" <= x <= "maximum value", why would
I want to make a special case for "minimum value" = 0?

#define MIN_VALUE 0 // Or any other value
#define MAX_VALUE 99 // Or any other value

File mycode.c:
int in_range (unsigned int x) {
#if MIN_VALUE <= 0
return x <= MAX_VALUE;
#else
return x >= MIN_VALUE && x <= MAX_VALUE;
#endif
}

Is that how you would want to write code?

Christian Bau, Feb 6, 2004