Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why unsigned int?

8 views
Skip to first unread message

none

unread,
May 20, 2010, 4:13:21 PM5/20/10
to
I often come across functions that takes an unsigned int as argument:

void somefunction(unsigned int i) {

}


I have also seen it used as template parameter for template classes:

template<typename T, unsigned int D=3>
class SomeClass {

};

Why use unsigned int in this context and not just int?

D. Stussy

unread,
May 20, 2010, 4:41:21 PM5/20/10
to
"none" <""mort\"@(none)"> wrote in message
news:4bf5983b$0$283$1472...@news.sunsite.dk...

Because negative values have no meaning in the context....


Kai-Uwe Bux

unread,
May 20, 2010, 4:46:22 PM5/20/10
to
none <""mort\"@(none)"> wrote:

> I often come across functions that takes an unsigned int as argument:
>
> void somefunction(unsigned int i) {

[...]


> }
>
>
> I have also seen it used as template parameter for template classes:
>
> template<typename T, unsigned int D=3>
> class SomeClass {
>
> };
>
> Why use unsigned int in this context and not just int?

You have actually not provided context. Sometimes, but not always, unsigned
int is better, sometimes but not always int is better, and there might even
be cases where one could go one way or the other without significant
difference. But, "SomeClass" is just not enough context to say _why_
unsigned would be better.

E.g.:

unsigned int number_of_bits_set ( unsigned int n ) {
...
}

could take an unsigned argument to ensure platform independence and to allow
for an easier portable implementation (signed integers can be represented in
two different ways on the bit-level).


Best

Kai-Uwe Bux

Öö Tiib

unread,
May 20, 2010, 5:02:27 PM5/20/10
to

But you did not post context. Context is how variable is used. Like
for example as right operand of bitwise shift operation. It does
*never* make sense to have negative value there.

Marcel Müller

unread,
May 20, 2010, 5:29:01 PM5/20/10
to
�� Tiib wrote:
> But you did not post context. Context is how variable is used. Like
> for example as right operand of bitwise shift operation. It does
> *never* make sense to have negative value there.

Well, an extended definition of shift operators may change the direction
in this case. Of, course the standard C++ operators do not.

However, there are many situations where a value must be a natural
number. Think about the length of a string or the number of elements in
an array or container or any other countable object.
One advantage of using unsigned integers in this cases is that you
usually need only one comparison to verify the validity of a value. E.g.:

unsigned index;
std::string str;
...
if (index >= str.length())
// Error
...

If you use singed int you have to check against zero too in general, to
avoid undefined behavior.

Of course, there are platforms where unsigned integers are slow, because
they are not supported by the hardware natively.


Marcel

Öö Tiib

unread,
May 20, 2010, 6:10:45 PM5/20/10
to
On 21 mai, 00:29, Marcel Müller <news.5.ma...@spamgourmet.org> wrote:

> Öö Tiib wrote:
> > But you did not post context. Context is how variable is used. Like
> > for example as right operand of bitwise shift operation. It does
> > *never* make sense to have negative value there.
>
> Well, an extended definition of shift operators may change the direction
> in this case. Of, course the standard C++ operators do not.

Yes. Especially because of that. Otherwise some inexperienced
maintainer might imagine it as extended.

> However, there are many situations where a value must be a natural
> number. Think about the length of a string or the number of elements in
> an array or container or any other countable object.
> One advantage of using unsigned integers in this cases is that you
> usually need only one comparison to verify the validity of a value. E.g.:
>
> unsigned index;
> std::string str;
> ...
> if (index >= str.length())
>    // Error
>    ...
>
> If you use singed int you have to check against zero too in general, to
> avoid undefined behavior.

That is the only significant advantage of using unsigned there but
that has been discussed to death. Lot of people for some reason prefer
-1 instead of 4294967295 there ... and since both are wrong values i
am indifferent. I am sure that reverse cycles using unsigned that way
may confuse the crap out of beginners however:

std::string str("Noob trap");
for ( unsigned i = str.size()-1; i < str.size(); --i )
{
str[i] += 13;
}

> Of course, there are platforms where unsigned integers are slow, because
> they are not supported by the hardware natively.

Yes, but on typical PC the division with constant is quicker for
unsigned (and so %). Conversion to float is quicker with signed. Rest
of the things are more or less at same speed. Also that speed is
*fast* in general so that is bad idea to adjust your type usage before
you have reasons to improve performance. Competitors throw something
together in python at same time and get the order while you ponder
about things that do not matter.

Kai-Uwe Bux

unread,
May 20, 2010, 6:29:23 PM5/20/10
to
�� Tiib wrote:

[...]


> I am sure that reverse cycles using unsigned that way
> may confuse the crap out of beginners however:
>
> std::string str("Noob trap");
> for ( unsigned i = str.size()-1; i < str.size(); --i )
> {
> str[i] += 13;
> }

[...]

That reminds me: when I first had to iterate backwards using unsigned int,
the above was the first idea that popped into my mind. When I posted it
here, somebody called it "evil" (I think) and taught me a more friendly
idiom:

for ( size_type i = str.size(); i-- > 0; ) {
...
}

At least, that does not rely on wrapping.


Best

Kai-Uwe Bux

Öö Tiib

unread,
May 20, 2010, 6:49:14 PM5/20/10
to
On 21 mai, 01:29, Kai-Uwe Bux <jkherci...@gmx.net> wrote:

Sure it is certainly less evil because smarter beginners can read it
out. Unless someone applies geek-beautifying like:

for ( size_type i = str.size(); i --> 0; ) {
...
}

Then explain what does operator-->(). Other thing is that it uses
operands with side-effects for comparison operator. That is something
that some policies forbid.

Alf P. Steinbach

unread,
May 20, 2010, 11:41:35 PM5/20/10
to
* �� Tiib, on 21.05.2010 00:10:
> On 21 mai, 00:29, Marcel M�ller<news.5.ma...@spamgourmet.org> wrote:

I think one can safely ignore the ENIACs...

But without proper support in place (a suitable general signed type, wrapper
functions for obtaining sizes, start-pointers and end-pointers of collections
and arrays) using signed integers can be a little laborious.

Proper support constitutes very little code, though. I wrote up about it here:
<url:
http://alfps.wordpress.com/2010/05/10/how-to-avoid-disastrous-integer-wrap-around/>

Cheers, & enjoy,

- Alf


--
blog at <url: http://alfps.wordpress.com>

Öö Tiib

unread,
May 21, 2010, 1:28:33 AM5/21/10
to
On May 21, 6:41 am, "Alf P. Steinbach" <al...@start.no> wrote:
>
> But without proper support in place (a suitable general signed type, wrapper
> functions for obtaining sizes, start-pointers and end-pointers of collections
> and arrays) using signed integers can be a little laborious.
>
> Proper support constitutes very little code, though. I wrote up about it here:
> <url: http://alfps.wordpress.com/2010/05/10/how-to-avoid-disastrous-integer-wrap-around/>

Yes, wrappers like that are probably needed to use signed values as
indexes.

It is maybe good to add that static_cast between signed and unsigned
integral types of same size takes 0 clock cycles on most popular
platforms (so that your progrock::cppx::size() has likely excellent
performance). ;)

Vladimir Jovic

unread,
May 21, 2010, 3:37:10 AM5/21/10
to
Kai-Uwe Bux wrote:
> [...]
>
> That reminds me: when I first had to iterate backwards using unsigned int,
> the above was the first idea that popped into my mind. When I posted it
> here, somebody called it "evil" (I think) and taught me a more friendly
> idiom:
>
> for ( size_type i = str.size(); i-- > 0; ) {
> ...
> }
>

Also known as the "goes to" operator :>

But it is like this :

James Kanze

unread,
May 21, 2010, 5:24:19 AM5/21/10
to
On 20 May, 23:10, Öö Tiib <oot...@hot.ee> wrote:
> On 21 mai, 00:29, Marcel Müller <news.5.ma...@spamgourmet.org> wrote:

> Yes, but on typical PC the division with constant is quicker for
> unsigned (and so %).

Are you sure. I think on a typical PC today, division is
a single clock, regardless of the type.

--
James Kanze

James Kanze

unread,
May 21, 2010, 5:28:04 AM5/21/10
to

> > [...]

And of course, there'll always be someone who'll convert it to
prefix decrementation, because somewhere, there's a rule to
prefer prefix to postfix.

In such cases, I'll just use a while:

size_t i = str.size();
while ( i != 0 ) {
-- i;
// ...
}

--
James Kanze

Öö Tiib

unread,
May 21, 2010, 7:13:31 AM5/21/10
to

I have to confess i haven't studied the differences between anyway
quick things much recently, usually improving bigger issues (with
threads and algorithms) helps lot more ... but this is like quite
recent Intels optimization manual ... http://www.intel.com/assets/pdf/manual/248966.pdf

It says somewhere things like:

> > The latency and throughput of IDIV in Enhanced Intel Core microarchitecture varies with operand sizes and with the number of significant digits of the quotient of the division. If the quotient is zero, the minimum latency can be 13 cycles, and the minimum throughput can be 5 cycles. Latency and throughput of IDIV increases with the number of significant digit of the quotient. The latency and
throughput of IDIV with 64-bit operand are significantly slower than
those with 32-bit operand. Latency of DIV is similar to IDIV.
Generally, the latency of DIV may be one cycle less.

Leigh Johnston

unread,
May 21, 2010, 8:01:08 AM5/21/10
to
"Alf P. Steinbach" <al...@start.no> wrote in message
news:ht4van$q4t$1...@news.eternal-september.org...

>
> But without proper support in place (a suitable general signed type,
> wrapper functions for obtaining sizes, start-pointers and end-pointers of
> collections and arrays) using signed integers can be a little laborious.
>
> Proper support constitutes very little code, though. I wrote up about it
> here:
> <url:
> http://alfps.wordpress.com/2010/05/10/how-to-avoid-disastrous-integer-wrap-around/>
>

So you have consolidated your bullshit opinion in a blog, well done.

There is nothing wrong with using unsigned integers, the C++ standard
library does it a lot hence the need for your retarded wrapper functions.
The C standard library also does it (look at strncpy and its size_t
parameter). Unsigned integers are not just for bit manipulation.

/Leigh

Leigh Johnston

unread,
May 21, 2010, 8:08:19 AM5/21/10
to
"Alf P. Steinbach" <al...@start.no> wrote in message
news:ht4van$q4t$1...@news.eternal-september.org...
>
> But without proper support in place (a suitable general signed type,
> wrapper functions for obtaining sizes, start-pointers and end-pointers of
> collections and arrays) using signed integers can be a little laborious.
>
> Proper support constitutes very little code, though. I wrote up about it
> here:
> <url:
> http://alfps.wordpress.com/2010/05/10/how-to-avoid-disastrous-integer-wrap-around/>
>

So you have consolidated your bullshit opinion in a blog, well done.

Leigh Johnston

unread,
May 21, 2010, 8:38:50 AM5/21/10
to

"Leigh Johnston" <le...@i42.co.uk> wrote in message
news:HbWdnVm2odsv6mvW...@giganews.com...

To clarify my reply: "hence the need" assuming you use ptrdiff_t everywhere
like you suggest rather than using the correct type for the job. :) In the
real world there is no need for your wrapper functions as your rationale for
them is simply to avoid the creation of bugs: this is an erroneous rationale
as if you were to take it to its logical conclusion a language would only be
"correct" if it had just *one* integral type.

/Leigh

Keith H Duggar

unread,
May 21, 2010, 2:54:15 PM5/21/10
to
On May 21, 5:24 am, James Kanze <james.ka...@gmail.com> wrote:
> On 20 May, 23:10, Öö Tiib <oot...@hot.ee> wrote:

>
> > On 21 mai, 00:29, Marcel Müller <news.5.ma...@spamgourmet.org> wrote:
> > Yes, but on typical PC the division with constant is quicker for
> > unsigned (and so %).
>
> Are you sure. I think on a typical PC today, division is
> a single clock, regardless of the type.

No. For example the following

int halfi ( int x ) { return x / 2 ; }
unsigned halfu ( unsigned x ) { return x / 2 ; }

compiled with

g++ --version
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5493)
Copyright (C) 2005 Free Software Foundation, Inc.

g++ -O3 -S

yields the following (cleaned up)

__Z5halfii:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
leave
movl %edx, %eax
shrl $31, %eax
addl %edx, %eax
sarl %eax
ret

__Z5halfuj:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
leave
shrl %eax
ret

Notice the int divide compiles to 3 Intel arithemtic instructions
and an extra move compared to the single instruction for unsigned.

KHD

Alf P. Steinbach

unread,
May 21, 2010, 3:34:34 PM5/21/10
to
* Keith H Duggar, on 21.05.2010 20:54:

As I recall there is SAR (Shift Arithmetic Right, signed div by 2) and SHR
(Shift Right, unsigned div by 2).

It seems you haven't turned on optimization, or compiler stupid, or my memory is
faulty (again), or, Intel has somehow turned those two instructions into
multiple clock cycle monstrosities?


Cheers,

Leigh Johnston

unread,
May 21, 2010, 3:46:17 PM5/21/10
to

"Alf P. Steinbach" <al...@start.no> wrote in message

news:ht6n4l$mqh$1...@news.eternal-september.org...

SAR is not sufficient as SAR(-1) == -1 which is obviously wrong, -1/2 = 0
not -1

/Leigh

Pete Becker

unread,
May 21, 2010, 3:58:03 PM5/21/10
to
On 2010-05-21 15:46:17 -0400, Leigh Johnston said:

>
> SAR is not sufficient as SAR(-1) == -1 which is obviously wrong, -1/2 =
> 0 not -1
>

Not according to the current C++ standard. It's implementation defined
which way the result gets rounded. And that's precisely because
hardware varies in how it handles cases like this. (Not to mention
that, algebraically, rounding in either direction makes just as much
sense). C++0x, in a burst of revisionism, requires truncating toward
zero.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Leigh Johnston

unread,
May 21, 2010, 4:00:18 PM5/21/10
to

"Pete Becker" <pe...@versatilecoding.com> wrote in message
news:2010052115580383262-pete@versatilecodingcom...

Huh? What you talking about? SAR is an intel opcode, nothing to do with
C++. I was talking about the SAR opcode, off-topic I know (blame Alf or
Keith).

/Leigh

Pete Becker

unread,
May 21, 2010, 4:10:41 PM5/21/10
to
On 2010-05-21 16:00:18 -0400, Leigh Johnston said:

> "Pete Becker" <pe...@versatilecoding.com> wrote in message
> news:2010052115580383262-pete@versatilecodingcom...
>> On 2010-05-21 15:46:17 -0400, Leigh Johnston said:
>>
>>>
>>> SAR is not sufficient as SAR(-1) == -1 which is obviously wrong, -1/2 =
>>> 0 not -1
>>>
>>
>> Not according to the current C++ standard. It's implementation defined
>> which way the result gets rounded. And that's precisely because
>> hardware varies in how it handles cases like this. (Not to mention
>> that, algebraically, rounding in either direction makes just as much
>> sense). C++0x, in a burst of revisionism, requires truncating toward
>> zero.
>>
>

> Huh? What you talking about? SAR is an intel opcode, nothing to do
> with C++. I was talking about the SAR opcode, off-topic I know (blame
> Alf or Keith).
>
>

I'm talking about the C++ requirements for division when one of the
operands is negative. And, oddly enough, this subthread is about
division. Which is why, I assume, you said "-1/2 = 0 not -1" to argue
that SAR wasn't "sufficient". -1/2 can produce a result of -1 under the
C++ rules.

Kai-Uwe Bux

unread,
May 21, 2010, 4:13:49 PM5/21/10
to
Leigh Johnston wrote:

>
>
> "Alf P. Steinbach" <al...@start.no> wrote in message
> news:ht6n4l$mqh$1...@news.eternal-september.org...
>> * Keith H Duggar, on 21.05.2010 20:54:
>>> On May 21, 5:24 am, James Kanze<james.ka...@gmail.com> wrote:

>>>> On 20 May, 23:10, ?�?? Tiib<oot...@hot.ee> wrote:

Just a nit: (-1)/2 == 0 is not guaranteed by the standard: the sign of the
remainder is implementation defined (that the quotient be rounded toward 0
is recommended is a footnote but not required). [5.6/4]

Nonetheless, in the above code, the compiler has to make sure that this use
of shifting implements the division by 2 properly (i.e. in accordance with
the implementation defined rules). As you point out, that explains the need
for the additional instructions.


Best

Kai-Uwe Bux

Leigh Johnston

unread,
May 21, 2010, 4:41:19 PM5/21/10
to
"Kai-Uwe Bux" <jkher...@gmx.net> wrote in message
news:ht6phv$o9g$1...@news.doubleSlash.org...

> Just a nit: (-1)/2 == 0 is not guaranteed by the standard: the sign of the
> remainder is implementation defined (that the quotient be rounded toward 0
> is recommended is a footnote but not required). [5.6/4]
>

"with any fractional part discarded" in the main standard text (not a
footnote) sounds pretty unambiguous to me, I cannot see how that would ever
result in -1/2 == -1, i.e. discarding the fractional part of -0.5 should
always result in 0. "discarding the fractional part" is not the same as
"rounding", it is the same as "truncating" (hence the footnote). This is
how I read it anyway, maybe am I wrong. If I am wrong I would appreciate
further citations or an example C++ implementation for which -1/2 == -1.

/Leigh

Paul Bibbings

unread,
May 21, 2010, 4:50:06 PM5/21/10
to
"Leigh Johnston" <le...@i42.co.uk> writes:

> "Kai-Uwe Bux" <jkher...@gmx.net> wrote in message
> news:ht6phv$o9g$1...@news.doubleSlash.org...
>> Just a nit: (-1)/2 == 0 is not guaranteed by the standard: the sign of the
>> remainder is implementation defined (that the quotient be rounded toward 0
>> is recommended is a footnote but not required). [5.6/4]
>>
>
> "with any fractional part discarded" in the main standard text

You appear to be quoting from the C++0x FCD which is, of course, not The
Standard yet (unless there was a change to this effect between C++98 and
C++03, only the former of which I have access to at the present).

Regards

Paul Bibbings

Leigh Johnston

unread,
May 21, 2010, 4:54:40 PM5/21/10
to

"Paul Bibbings" <paul.b...@gmail.com> wrote in message
news:87k4qxr...@gmail.com...

Yes I was, the draft C standard has similar wording too which is why I
assumed it was older wording but it looks like C guys and C++ guys are
working in unison on this point (assuming you are correct, could you cite
the current standard which I don't have?). Either way the next revision of
the standard should put any retarded implementations which evaluate -1/2
as -1 to bed. :)

/Leigh

Paul Bibbings

unread,
May 21, 2010, 5:06:28 PM5/21/10
to
"Leigh Johnston" <le...@i42.co.uk> writes:

[expr.mul]/4

"The binary / operator yields the quotient, and the binary % operator
yields the remainder from the division of the first expression by the
second. If the second operand of / or % is zero the behavior is
undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are
nonnegative then the remainder is nonnegative; if not, the sign of the
remainder is implementation-defined 74)."

74) "According to work underway toward the revision of ISO C, the
preferred algorithm for integer division follows the rules defined
in the ISO Fortran standard, ISO/IEC 1539:1991, in which the
quotient is always rounded towards zero."

This is according to C++98. I don't have access immediately to C++03,
and so I don't know what the implications are for the possibility of
this having changed in the 5 intervening years, particularly given the
intention expressed in the footnote.

Regards

Paul Bibbings

Kai-Uwe Bux

unread,
May 21, 2010, 5:11:39 PM5/21/10
to
Leigh Johnston wrote:

>
>
> "Paul Bibbings" <paul.b...@gmail.com> wrote in message
> news:87k4qxr...@gmail.com...
>> "Leigh Johnston" <le...@i42.co.uk> writes:
>>
>>> "Kai-Uwe Bux" <jkher...@gmx.net> wrote in message
>>> news:ht6phv$o9g$1...@news.doubleSlash.org...
>>>> Just a nit: (-1)/2 == 0 is not guaranteed by the standard: the sign of
>>>> the
>>>> remainder is implementation defined (that the quotient be rounded
>>>> toward 0
>>>> is recommended is a footnote but not required). [5.6/4]
>>>>
>>>
>>> "with any fractional part discarded" in the main standard text
>>
>> You appear to be quoting from the C++0x FCD which is, of course, not The
>> Standard yet (unless there was a change to this effect between C++98 and
>> C++03, only the former of which I have access to at the present).
>>
>> Regards
>>
>> Paul Bibbings
>
> Yes I was, the draft C standard has similar wording too which is why I
> assumed it was older wording but it looks like C guys and C++ guys are
> working in unison on this point (assuming you are correct, could you cite
> the current standard which I don't have?).

Current [5.6/4] in C++03:

The binary / operator yields the quotient, and the binary % operator yields
the remainder from the division of the first expression by the second. If
the second operand of / or % is zero the behavior is undefined; otherwise
(a/b)*b + a%b is equal to a. If both operands are nonnegative then the

remainder is nonnegative; if not, the sign of the remainder is
implementation-defined.

> Either way the next revision of the standard should put any retarded
> implementations which evaluate -1/2 as -1 to bed. :)

It's not retarded, it makes it so that a % 2 is always 0 or 1.


Best

Kai-Uwe Bux

Leigh Johnston

unread,
May 21, 2010, 5:13:28 PM5/21/10
to
"Kai-Uwe Bux" <jkher...@gmx.net> wrote in message
news:ht6sub$ou1$1...@news.doubleSlash.org...

>> Either way the next revision of the standard should put any retarded
>> implementations which evaluate -1/2 as -1 to bed. :)
>
> It's not retarded, it makes it so that a % 2 is always 0 or 1.
>

-1/2 == -1 is retarded.

/Leigh

Kai-Uwe Bux

unread,
May 21, 2010, 5:39:34 PM5/21/10
to
Leigh Johnston wrote:

Why?


E.g., say you want to implement a circular buffer, it would sure come in
handy just to code a shift of the current location by an arbitrary
displacement as

index = ( index + shift ) % size;

where shift could be negative. If % can yield negative results, one would
have to use more words unless, of course, the standard abandons the
invariant:

(a/b) * b + (a%b) == a

(which it won't).


What is a bit unfortunate is that the rules for / and % were implementation
defined for negative arguments. At least that is going to change. However, I
cannot see that the (not chosen) convention to have the remainder always be
positive is "retarded". I do not even see that it has a clear-cut advantage.
Could you provide a few?


Best

Kai-Uwe Bux

Leigh Johnston

unread,
May 21, 2010, 5:58:41 PM5/21/10
to

"Kai-Uwe Bux" <jkher...@gmx.net> wrote in message

news:ht6uim$p8l$1...@news.doubleSlash.org...


> Leigh Johnston wrote:
>
>> "Kai-Uwe Bux" <jkher...@gmx.net> wrote in message
>> news:ht6sub$ou1$1...@news.doubleSlash.org...
>>>> Either way the next revision of the standard should put any retarded
>>>> implementations which evaluate -1/2 as -1 to bed. :)
>>>
>>> It's not retarded, it makes it so that a % 2 is always 0 or 1.
>>>
>>
>> -1/2 == -1 is retarded.
>
> Why?
>
>
> E.g., say you want to implement a circular buffer, it would sure come in
> handy just to code a shift of the current location by an arbitrary
> displacement as
>
> index = ( index + shift ) % size;
>
> where shift could be negative. If % can yield negative results, one would
> have to use more words unless, of course, the standard abandons the
> invariant:
>
> (a/b) * b + (a%b) == a
>
> (which it won't).
>

If you substitute -11 for a and 3 for b you get:

(-11/3) * 3 + (-11%3) = -11

If the division does not "round" toward zero then (-11/3) = -4 so:

(-4) * 3 + (-11%3) = -11

so

(-11%3) = -11 - -12 = 1

How useful is that? To me (-11%3) = -2 makes sense. Truncation toward zero
makes sense for me, anything else gives me a headache.

/Leigh

none

unread,
May 21, 2010, 5:49:19 PM5/21/10
to
D. Stussy wrote:
> "none" <""mort\"@(none)"> wrote in message
> news:4bf5983b$0$283$1472...@news.sunsite.dk...
>> I often come across functions that takes an unsigned int as argument:
>>
>> void somefunction(unsigned int i) {
>> }
>>
>> I have also seen it used as template parameter for template classes:
>>
>> template<typename T, unsigned int D=3>
>> class SomeClass {
>>
>> };
>>
>> Why use unsigned int in this context and not just int?
>
> Because negative values have no meaning in the context....
>
>

Ok so its a way of indicating that only positive arguments will be passed for this function? But is
there any performance increase?

Kai-Uwe Bux

unread,
May 21, 2010, 6:08:11 PM5/21/10
to
Leigh Johnston wrote:

See the quoted code for example how that can be useful.

> To me (-11%3) = -2 makes sense.

Sure does, but so does -11%3 = 1

> Truncation toward zero makes sense for me, anything else gives me a
> headache.

So it comes down to a personal preference. Well, that's fine.


Best

Kai-Uwe Bux

Leigh Johnston

unread,
May 21, 2010, 6:19:15 PM5/21/10
to

"Kai-Uwe Bux" <jkher...@gmx.net> wrote in message

news:ht708b$pg3$1...@news.doubleSlash.org...


> Leigh Johnston wrote:
>> Truncation toward zero makes sense for me, anything else gives me a
>> headache.
>
> So it comes down to a personal preference. Well, that's fine.
>

Not really, mathematically speaking -(a/b) is equivalent to (-a/b) and not
having such equivalence in the language seems wrong to me.

-(1/2) = 0 = (-1/2)

This property is more important to me than the property of having a modulo
always produce positive (but non-intuitive) results. Maybe I am missing
something fundamental here.

/Leigh

James Kanze

unread,
May 21, 2010, 6:22:18 PM5/21/10
to

> >> void somefunction(unsigned int i) {
> >> }

It's not even that. It's a way of indicating whatever the local
coding conventions say that it indicates. Or a way of
indicating that plain int won't do the job, for some reason.
(Perhaps because the value will be >>'ed.)

> But is there any performance increase?

In general, the *standard* type for any integer value is int.
Almost by definition, no other type can result in a performance
increase. (On a very few platforms, unsigned will result in a
noticeable decrease in performance.)

--
James Kanze


Leigh Johnston

unread,
May 21, 2010, 6:26:32 PM5/21/10
to
"James Kanze" <james...@gmail.com> wrote in message
news:a05294db-a50e-4e5c...@y21g2000vba.googlegroups.com...

>
>> But is there any performance increase?
>
> In general, the *standard* type for any integer value is int.
> Almost by definition, no other type can result in a performance
> increase. (On a very few platforms, unsigned will result in a
> noticeable decrease in performance.)
>
> --
> James Kanze
>

As has been shown else-thread the reverse can also be true (unsigned can
result in an increase in performance, or less CPU instructions emitted at
least). Still, it smells of premature optimization to me.

/Leigh

Kai-Uwe Bux

unread,
May 21, 2010, 6:41:55 PM5/21/10
to
Leigh Johnston wrote:

>
>
> "Kai-Uwe Bux" <jkher...@gmx.net> wrote in message
> news:ht708b$pg3$1...@news.doubleSlash.org...
>> Leigh Johnston wrote:
>>> Truncation toward zero makes sense for me, anything else gives me a
>>> headache.
>>
>> So it comes down to a personal preference. Well, that's fine.
>>
>
> Not really, mathematically speaking -(a/b) is equivalent to (-a/b) and not
> having such equivalence in the language seems wrong to me.
>
> -(1/2) = 0 = (-1/2)

Well, mathematically, -1/2 = -0.5. And now, the question is just about
rounding :-)

Nonetheless, I see the point.



> This property is more important to me than the property of having a modulo
> always produce positive (but non-intuitive) results.

I view % as an operator that returns the canonical representative of a
congruence class, and to me it's intuitive that congruence classes mod 3
should be represented by 0, 1, and 2. That the canonical representative of a
congruence class should depend not only on the congruence class but on which
particular representative I chose to find the canonical representative, that
is non-intuitive to me. (And it is inconvenient in programming with
congruence classes.)

> Maybe I am missing something fundamental here.

Not really, it's just different points of view. I tend to view % as
important and appreciate nice and useful properties of %. But I can
certainly see that / could be more within focus for other people.


Best

Kai-Uwe Bux

Kai-Uwe Bux

unread,
May 21, 2010, 6:46:37 PM5/21/10
to
James Kanze wrote:

> On May 21, 10:49 pm, none <""mort\"@(none)"> wrote:

[...]


>> But is there any performance increase?
>
> In general, the *standard* type for any integer value is int.
> Almost by definition, no other type can result in a performance
> increase.

[...]

That is certainly not a matter of definition. The standard requires that int
be signed. Thus, all the "definition" can stipulate is that int be the
fastest signed type. Even if an unsigned type was faster on a given
architecture, the compiler writer could not choose that one for int.

Nonetheless, as a matter of fact (not of definition), it can still be true
that processors are optimized for operating with signed rather than unsigned
types (especially since the unsigned types in c++ have to implement modular
arithmetic for +,-, and *).


Best

Kai-Uwe Bux

Keith H Duggar

unread,
May 21, 2010, 8:50:53 PM5/21/10
to
On May 21, 3:34 pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * Keith H Duggar, on 21.05.2010 20:54:
> > On May 21, 5:24 am, James Kanze<james.ka...@gmail.com> wrote:
> >> On 20 May, 23:10, Öö Tiib<oot...@hot.ee> wrote:

Obviously since the code I posted uses both SAR and SHR. There
really is nothing to "recall" at that point. Did you read the
entire post?

> It seems you haven't turned on optimization,

I posted the command I used "g++ -O3 -S" so that's obviously
a false wild-ass guess.

> or compiler stupid

Right ... let's just assume the compiler is stupid. Geesh.

> or, Intel has somehow turned those two instructions into
> multiple clock cycle monstrosities?

Right ... let's just assume Intel is stupid. Geesh.

I guess it is just human nature (for some) to pay so little
respect to the giants all around us. To just assume they are
big stupid lumbering oafs before even bothering to pour one
drop of thought into the problem at hand.

The code generated is the fastest way implement truncated ie
round-to-zero division on Intel. There is no stupidity involved,
just basic ignorance as usual for USENET.

Also, by the way, division is generally NOT a single operation
or clock and in fact depends on the inputs. The same is true for
division by a constant where the number of operations (combos of
shift, add, and multiplies) required will depend on the structure
of the divisor. This is basic computer engineering covered all
over academia and the web. Here is a nice tutorial for you:

http://www.cs.uiowa.edu/~jones/bcd/divide.html

KHD

Alf P. Steinbach

unread,
May 22, 2010, 12:58:59 AM5/22/10
to
* Keith H Duggar, on 22.05.2010 02:50:

I skimmed it. AT&T syntax looks like gobbledegook to me. Sorry.


>> It seems you haven't turned on optimization,
>
> I posted the command I used "g++ -O3 -S" so that's obviously
> a false wild-ass guess.
>
>> or compiler stupid
>
> Right ... let's just assume the compiler is stupid. Geesh.
>
>> or, Intel has somehow turned those two instructions into
>> multiple clock cycle monstrosities?
>
> Right ... let's just assume Intel is stupid. Geesh.
>
> I guess it is just human nature (for some) to pay so little
> respect to the giants all around us. To just assume they are
> big stupid lumbering oafs before even bothering to pour one
> drop of thought into the problem at hand.

I don't like your piecemeal quoting of a sentence, pretending you quoted the
full sentence. But, you're upset, naturally, and then such techniques and some
verbiage may seem called for. The morons here, like me, just hazily recollect
some assembly from decades ago instead of studying your AT&T syntax example...


> The code generated is the fastest way implement truncated ie
> round-to-zero division on Intel. There is no stupidity involved,
> just basic ignorance as usual for USENET.

It may well be the fastest. At least on my old clunky computer using a jump for
sign testing was 5 to 10% slower (I thought perhaps so little code would fit
into some internal cache, and then with the magic predictive powers of processor
perhaps fewer ops on average, but no), and incredibly to me, but perhaps not to
some doing assembly programming on modern computers daily, using bit-testing was
about 50% slower.

On the other hand, shaving off the stack frame maintainance reduced the call
time by 10 or 15% or so, e.g. now 0.188 seconds versus 0.219 seconds for my test
program. Well it might confuse the gdb debugger to not have that frame. But then
gdb is so easily confused by just about anything. :-)


<code compiler="g++">
extern "C" int aHalfI( int x );
__asm (
".intel_syntax noprefix \n"
".globl _aHalfI \n"
"_aHalfI: \n"
" mov eax, [esp+4] \n"
" mov edx, eax \n"
" shr edx, 31 \n"
" lea eax, [edx+eax] \n"
" sar eax \n"
" ret \n"
".att_syntax \n"
);
</code>


Just to be clear, that shave has nothing to do with the division itself.


> Also, by the way, division is generally NOT a single operation
> or clock and in fact depends on the inputs. The same is true for
> division by a constant where the number of operations (combos of
> shift, add, and multiplies) required will depend on the structure
> of the divisor. This is basic computer engineering covered all
> over academia and the web. Here is a nice tutorial for you:
>
> http://www.cs.uiowa.edu/~jones/bcd/divide.html
>
> KHD

Thanks. I probably don't need it. But resources are always great.

Öö Tiib

unread,
May 22, 2010, 7:41:24 AM5/22/10
to
On 22 mai, 07:58, "Alf P. Steinbach" <al...@start.no> wrote:
> * Keith H Duggar, on 22.05.2010 02:50:

Wow, you people made such a comp.lang.asm discussion out of my simple
remark that signed division is slightly slower? For Intel it may take
slightly more. Division takes more cycles itself (but nothing like 40
cycles it did take old days). It is worth to optimize, but that is
what compilers do already well.

Also, division is usually not needed anywhere if you use signed value
as array index. Multiplication is used and it is about equal for both
signed and unsigned (but also not 1 cycle, but there are pipelines, so
independent instructions may be done in parallel).

The thing i hate about it is when people in same team start to argue
what is better index and then one uses signed index and other uses
unsigned index. It inevitably results with need to mix signed and
unsigned math and so it is good idea to demand them toss a coin and
then write the result down as policy.

Keith H Duggar

unread,
May 22, 2010, 2:56:07 PM5/22/10
to
On May 22, 12:58 am, "Alf P. Steinbach" <al...@start.no> wrote:
> * Keith H Duggar, on 22.05.2010 02:50:
> > On May 21, 3:34 pm, "Alf P. Steinbach"<al...@start.no> wrote:
> >> * Keith H Duggar, on 21.05.2010 20:54:
> >>> On May 21, 5:24 am, James Kanze<james.ka...@gmail.com> wrote:
> >>>> On 20 May, 23:10, Öö Tiib<oot...@hot.ee> wrote:

Ok, you ignored the AT&T asm. That doesn't explain how you missed
"g++ -O3 -S" leading you to falsely wild-ass guess that I didn't
turn optimization on. Maybe that is because of the "skimming" you
did instead of /reading/?

> >> It seems you haven't turned on optimization,
>
> > I posted the command I used "g++ -O3 -S" so that's obviously
> > a false wild-ass guess.
>
> >> or compiler stupid
>
> > Right ... let's just assume the compiler is stupid. Geesh.
>
> >> or, Intel has somehow turned those two instructions into
> >> multiple clock cycle monstrosities?
>
> > Right ... let's just assume Intel is stupid. Geesh.
>
> > I guess it is just human nature (for some) to pay so little
> > respect to the giants all around us. To just assume they are
> > big stupid lumbering oafs before even bothering to pour one
> > drop of thought into the problem at hand.
>
> I don't like your piecemeal quoting of a sentence,

I'm sure you don't as it puts into stark relief your various
faulty assumptions namely:

1) the poster is stupid
2) g++ is stupid
3) Intel is stupid.

Why do you do that? Why don't you instead either 1) /read/ the
post and /think/ about before responding 2) not respond at all?
Either of those is far more reasonable that not bothering to
read and assuming one or all of the other parties is stupid.

> pretending you quoted the full sentence.

Huh? I don't see any "pretending" at all. If you are going to
write a disjunction of multiple crap assumptions, don't be upset
that another splits them up to respond to each in turn.

> But, you're upset, naturally, and then such techniques and some
> verbiage may seem called for.

LOL, yeah let's speculate about each other's emotion. That will
be MOST productive. You know for somebody who recently posted a
"why did I act that way" post reminiscing former bad behavior,
you are surprisingly slow to learn from your mistakes.

> The morons here, like me, just hazily recollect some assembly
> from decades ago instead of studying your AT&T syntax example...

Yes, haste makes waste. But not only did hastily recollect some
past knowledge, you also 1) failed to bother reading the post to
the point of missing something as obvious as "-O3" 2) made some
rather foolish and arrogant assumptions about the poster, the
compiler, and chip manufacturer being stupid. How do you explain
those actions?

> > Also, by the way, division is generally NOT a single operation
> > or clock and in fact depends on the inputs. The same is true for
> > division by a constant where the number of operations (combos of
> > shift, add, and multiplies) required will depend on the structure
> > of the divisor. This is basic computer engineering covered all
> > over academia and the web. Here is a nice tutorial for you:
>
> > http://www.cs.uiowa.edu/~jones/bcd/divide.html
>

> Thanks. I probably don't need it. But resources are always great.

Especially true if you are going to "skim" it with the same acuity
you did my post. I'm sure you would find it as equally stupid as say
g++ and Intel.

KHD

Alf P. Steinbach

unread,
May 22, 2010, 3:51:19 PM5/22/10
to
* Keith H Duggar, on 22.05.2010 20:56:

>
> Yes, haste makes waste. But not only did hastily recollect some
> past knowledge, you also 1) failed to bother reading the post to
> the point of missing something as obvious as "-O3" 2) made some
> rather foolish and arrogant assumptions about the poster, the
> compiler, and chip manufacturer being stupid. How do you explain
> those actions?

You're lying.

Kai-Uwe Bux

unread,
May 22, 2010, 3:55:14 PM5/22/10
to
Alf P. Steinbach wrote:

> * Keith H Duggar, on 22.05.2010 20:56:
>>
>> Yes, haste makes waste. But not only did hastily recollect some
>> past knowledge, you also 1) failed to bother reading the post to
>> the point of missing something as obvious as "-O3" 2) made some
>> rather foolish and arrogant assumptions about the poster, the
>> compiler, and chip manufacturer being stupid. How do you explain
>> those actions?
>
> You're lying.

I don't think so. I have the impression that (a) he is not trying to deceive
anybody and (b) that he honestly believes what he writes. That alone (not
even accounting for the possibility that he could be right) rules out that
he is lying.


Best

Kai-Uwe Bux

Alf P. Steinbach

unread,
May 22, 2010, 4:07:34 PM5/22/10
to
* Kai-Uwe Bux, on 22.05.2010 21:55:

He can't honestly believe that I've called him stupid (just to take one very
clear-cut example). Hence, he's lying.

That's also indicated by selective quoting and other mislead-the-reader tactics,
which probably is why you've got "impressions": that's what such tactics are all
about, creating impressions.

But one can't conclude 100% that a person lies just on the basis of overwhelming
indications. With a clear falsehood it is however easy. He's lying.

Kai-Uwe Bux

unread,
May 22, 2010, 4:14:04 PM5/22/10
to
Alf P. Steinbach wrote:

> * Kai-Uwe Bux, on 22.05.2010 21:55:
>> Alf P. Steinbach wrote:
>>
>>> * Keith H Duggar, on 22.05.2010 20:56:
>>>>
>>>> Yes, haste makes waste. But not only did hastily recollect some
>>>> past knowledge, you also 1) failed to bother reading the post to
>>>> the point of missing something as obvious as "-O3" 2) made some
>>>> rather foolish and arrogant assumptions about the poster, the
>>>> compiler, and chip manufacturer being stupid. How do you explain
>>>> those actions?
>>>
>>> You're lying.
>>
>> I don't think so. I have the impression that (a) he is not trying to
>> deceive anybody and (b) that he honestly believes what he writes. That
>> alone (not even accounting for the possibility that he could be right)
>> rules out that he is lying.
>
> He can't honestly believe that I've called him stupid (just to take one
> very clear-cut example). Hence, he's lying.

He did not say that you "called" him stupid. His statement is consistent
with the interpretation that you _implied_ he was stupid. Maybe, he takes
your conjecture that he did not turn on optimization to be meant like that.

[...]

> But one can't conclude 100% that a person lies just on the basis of
> overwhelming indications. With a clear falsehood it is however easy. He's
> lying.

I don't see a "clear falsehood".


Best

Kai-Uwe Bux

Keith H Duggar

unread,
May 22, 2010, 4:27:02 PM5/22/10
to

On May 22, 4:14 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Alf P. Steinbach wrote:
> > * Kai-Uwe Bux, on 22.05.2010 21:55:
> >> Alf P. Steinbach wrote:
>
> >>> * Keith H Duggar, on 22.05.2010 20:56:
>
> >>>> Yes, haste makes waste. But not only did hastily recollect some
> >>>> past knowledge, you also 1) failed to bother reading the post to
> >>>> the point of missing something as obvious as "-O3" 2) made some
> >>>> rather foolish and arrogant assumptions about the poster, the
> >>>> compiler, and chip manufacturer being stupid. How do you explain
> >>>> those actions?
>
> >>> You're lying.
>
> >> I don't think so. I have the impression that (a) he is not trying to
> >> deceive anybody and (b) that he honestly believes what he writes. That
> >> alone (not even accounting for the possibility that he could be right)
> >> rules out that he is lying.
>
> > He can't honestly believe that I've called him stupid (just to take one
> > very clear-cut example). Hence, he's lying.
>
> He did not say that you "called" him stupid. His statement is consistent
> with the interpretation that you _implied_ he was stupid. Maybe, he takes
> your conjecture that he did not turn on optimization to be meant like that.

Precisely. If one is taking the trouble to post compiler generated
assembly in response to a point about int/unsigned being "quicker",
it indeed would be stupid not to turn optimization on!

> > But one can't conclude 100% that a person lies just on the basis of
> > overwhelming indications. With a clear falsehood it is however easy. He's
> > lying.
>
> I don't see a "clear falsehood".

Neither do I. However, I do see that behind this smoke screen Alf
has managed to avoid addressing the other charges even if he does
not stipulate this ONE of the several.

KHD

Alf P. Steinbach

unread,
May 22, 2010, 4:39:51 PM5/22/10
to
* Kai-Uwe Bux, on 22.05.2010 22:14:

> Alf P. Steinbach wrote:
>
>> * Kai-Uwe Bux, on 22.05.2010 21:55:
>>> Alf P. Steinbach wrote:
>>>
>>>> * Keith H Duggar, on 22.05.2010 20:56:
>>>>>
>>>>> Yes, haste makes waste. But not only did hastily recollect some
>>>>> past knowledge, you also 1) failed to bother reading the post to
>>>>> the point of missing something as obvious as "-O3" 2) made some
>>>>> rather foolish and arrogant assumptions about the poster, the
>>>>> compiler, and chip manufacturer being stupid. How do you explain
>>>>> those actions?
>>>>
>>>> You're lying.
>>>
>>> I don't think so. I have the impression that (a) he is not trying to
>>> deceive anybody and (b) that he honestly believes what he writes. That
>>> alone (not even accounting for the possibility that he could be right)
>>> rules out that he is lying.
>>
>> He can't honestly believe that I've called him stupid (just to take one
>> very clear-cut example). Hence, he's lying.
>
> He did not say that you "called" him stupid. His statement is consistent
> with the interpretation that you _implied_ he was stupid. Maybe, he takes
> your conjecture that he did not turn on optimization to be meant like that.

However a set of lies is packaged in weasel words like "made some assumptions
about" that can be unnaturally interpreted as if it didn't mean that it was
written but was the poster's impression, doesn't make it less of a set of lies.

Anyway, I haven't stated any such assumptions, and I did not make them, and even
if I had Keith is not a telepath and couldn't know. He might as well say that
you had "made some assumptions about" Barack Obama being an alcoholic. Whether
true or not (AFAIK it's not), and whether you could imagine that that was his
impression, it would be a lie about you if you had not expressed that.

In short, with a direct falsehood the conclusion is firm: it's lying.


> [...]
>
>> But one can't conclude 100% that a person lies just on the basis of
>> overwhelming indications. With a clear falsehood it is however easy. He's
>> lying.
>
> I don't see a "clear falsehood".

I see a number of them. :-)

Öö Tiib

unread,
May 22, 2010, 6:14:06 PM5/22/10
to

All you said was that:

>>> It seems you haven't turned on optimization, or compiler stupid, or my memory
>>> is faulty (again), or, Intel has somehow turned those two instructions into
>>> multiple clock cycle monstrosities?

So if Keith finds that him posting something about performance without
turning on optimizations implies that he is stupid, about g++ your
words were explicit, about your memory he skimmed ;) and about Intel
it again sounds like something irrational done.

I feel that Keith interprets that the parts of your sentence had *AND*
between them (so everyone in that row are stupid) while there was
clearly *OR*. So you can safely say that your memory was faulty, and
no one has been insulted?

cpp4ever

unread,
May 23, 2010, 4:55:44 AM5/23/10
to
On 05/20/2010 09:13 PM, none wrote:
> I often come across functions that takes an unsigned int as argument:
>
> void somefunction(unsigned int i) {
>
>
>
> }
>
>
> I have also seen it used as template parameter for template classes:
>
> template<typename T, unsigned int D=3>
> class SomeClass {
>
> };
>
> Why use unsigned int in this context and not just int?

I'd call it a positive outlook

JB

James Kanze

unread,
May 24, 2010, 5:56:25 PM5/24/10
to
On May 22, 1:50 am, Keith H Duggar <dug...@alum.mit.edu> wrote:
> On May 21, 3:34 pm, "Alf P. Steinbach" <al...@start.no> wrote:

[...]


> Also, by the way, division is generally NOT a single operation
> or clock and in fact depends on the inputs.

The last time I ran my benchmarks on a modern Sparc, all four
operations (addition, subtraction, multiplication and division)
took exactly the same time. Regardless of the arguments. (This
wasn't true in the past: +, -, * and all four floating point
operations took the same time, but integral division was slower.
But that was in the past.)

--
James Kanze

Keith H Duggar

unread,
May 24, 2010, 6:18:25 PM5/24/10
to

Post the benchmarking code, methods, and results.

KHD

James Kanze

unread,
May 25, 2010, 4:31:59 PM5/25/10
to

> > [...]

I can't, since I didn't save them, and I don't currently have
access to a Sparc.

The code itself is available at my site: the Operator benchmark.

--
James Kanze

Keith H Duggar

unread,
May 27, 2010, 9:43:43 PM5/27/10
to

That's ok. We have the hard facts from the Sun engineers themselves.
For example see Tables 7.2 and 7.3 (and for detail on specifically
division section 7.9) in the SPARC T2 specification:

https://www.opensparc.net/pubs/t2/docs//OpenSPARCT2_Core_Micro_Arch.pdf

Division is many times slower than add, subtract, multiply, etc.
For those that don't want to look here are the throughput numbers:

op : type : clocks
+ : INT : 1
* : INT : 1
/ : INT : 13 to 41 depending on input values
+ : SPF : 1
* : SPF : 1
/ : SPF : 19
/ : DPF : 33

INT = integer, S(D)PF = single(double) precision float. Which
among other things confirms that division is much slower than
other ops and integer division depends on the inputs (as does
float division in some special cases, see the discussion in
section 7.9).

> The code itself is available at my site: the Operator benchmark.

Thanks. I've look at your site in the past, lots of nice stuff
there. Still waiting for you to write a book someday about your
C++ career ;-)

Unfortunately, I can see now why you were so mislead regarding
division. The OOness of your benchmarking code might be ok for
slow functions (hundreds or thousands of clocks) however it is
broken for measuring low level single instruction timings. For
one the code measurements are being dominated by the overheads
for example the virtual function calling; and unless I missed
it, no steps are taken to remove this overhead pollution from
the underlying signal. For single ops the signal is going to
be very small by comparison.

Also, I find it interesting that you concluded there is no
dependence on input values when you have hard coded 1 and 2 as
the operands?

There are a number of other problems also. You can look at my
circle drawing profiling code to see examples of the lengths
one must go to in order to accurately profile such tiny low
level functions:

http://www.duggar.org/pub/code/circle/

It's certainly not pretty but it gets the job done accurately.

KHD

0 new messages