Unsigned integer in loops

I would like to know why the first loop works meanwhile the second doesn't. I also would like to know why both loops end, for me, they should be an infinite loop.

This one works
 
for (unsigned int i = v.size()-1; i != -1; --i) reverse.push_back(v[i]);


This one does nothing
 
for (unsigned int i = v.size()-1; i > -1; --i) reverse.push_back(v[i]);


If anyone needs the full program for something here it is, it basically reverses a vector knowing its size without using algorithm library and prints it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
using namespace std;

void v_reverse (const vector <int> &v) {
	vector <int> reverse;
	for (unsigned int i = v.size()-1; i != -1; --i) reverse.push_back(v[i]);
	for (unsigned int i = 0; i < reverse.size(); ++i) {
		cout << reverse[i];
		if (i != reverse.size()-1) cout << " ";
	}
}

int main () {
	int size;
	while (cin >> size) {
		vector <int> v (size);
		for (int i = 0; i < size; ++i) cin >> v[i];
		v_reverse (v);
		cout << endl;
	}
}
Last edited on
I would like to know why the first loop works meanwhile the second doesn't.

What do you mean by not working?

I also would like to know why both loops end, for me, they should be an infinite loop.

What makes you think they should both be infinite loops?

This one does nothing

What do you mean by "does nothing"?

Have you run the program with your debugger? Put a break point somewhere before that code and then single step through the loop watching the variables as you loop.


Don't forget that since i is an unsigned int it will never be negative, -1 will actually be a very large positive value (the largest value that can be contained in a unsigned int).


Also std::vector.size() returns a size_t, which is an implementation defined unsigned type. It may be something other than an unsigned int, it could be an unsigned long, or even an unsigned long long. You really should be using a size_t of i instead of unsigned int.

Okay, tested it with the following program and saw myself that program does not enter the second loop.
I would like to know why, for me, it makes more sense that the programs would ignore the first loop and go for the second loop, but that doesn't seem the case:

1
2
3
4
5
6
7
#include <iostream>
using namespace std;

int main () {
	for (unsigned int i = 4; i != -1; --i) cout << "I enter loop i != -1" << endl;
	for (unsigned int i = 4; i > -1; --i) cout << "I enter loop i > -1" << endl;
}



Output:
I enter loop i != -1
I enter loop i != -1
I enter loop i != -1
I enter loop i != -1
I enter loop i != -1


I also tried using this for (unsigned int i = 4; i >= 0; --i) cout << "I enter loop i >= 0" << endl; this creates an endless loop as I expected


Also std::vector.size() returns a size_t, which is an implementation defined unsigned type. It may be something other than an unsigned int, it could be an unsigned long, or even an unsigned long long. You really should be using a size_t of i instead of unsigned int.

Using size_t with the same program gives same output as before and I would like not to use size_t.
Last edited on
Check this:

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;

int main () {
	cout << "-1 = " << (unsigned int) -1 << endl;

	for (unsigned int i = 4; i != -1; --i) cout << "I enter loop i != -1" << endl;
	for (unsigned int i = 4; i > -1; --i) cout << "I enter loop i > -1" << endl;
}
Okay now I understand why the second loop is ignored but I have a question now for the first loop, shouldn't it be infinite then?

Also why -1 unsigned int becomes (2^32) -1 = 4294967295
-2 is (-1 unsigned int) -1 = 4294967294
So if we test this we can see that -4294967295 unsigned int = 1

AMAZING!
Last edited on
Why would it ignore the first loop? You're decrementing i when it first decrements past zero it becomes the highest possible value for the type (4294967295), so the comparison would then be false since 4294967295 is equal to 4294967295.

Why would you expect the second loop to ever execute? The variable i can never be greater than -1, or more precisely 4294967295. An unsigned int can never be negative. And because you're actually comparing the number to the highest possible value that can be held in the unsigned int type i will never be greater than -1 (4294967295).

Try this program for illustration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main () 
{
    unsigned int test = -1;

    cout << test << endl;

   if(test > -1) // Remember this is actually (test > 4294967295).
       cout << "test is greater than -1 or (4294967295)\n";
   else
       cout << "test is not greater than -1 or (4294967295)\n";
}


But note that you should be getting a warning for this program (and your program as well):
In function 'int main()': 10:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]


Yes, I saw that with coder777 program.

But now I have 2 questions:

First one: Shouldn't the first loop be infinite then?

Second one: Why -x unsigned int = (2^32) -x
Last edited on
First one: Shouldn't the first loop be infinite then?

No, i can be equal to unsigned int<max> (4294967295) when you decrement i past zero.

Second one: Why -x unsigned int = (2^32) -x

You may want to study this link:
http://stackoverflow.com/questions/1049722/what-is-2s-complement

I know what the 2 complement is, but why use it on unsigned integers if they are mean to always be positive, wouldn't it be better to do another "thing" like for example take the absolute value of the unsigned int so if it's -1 it becomes 1.

Can it be useful the 2 complement when using unsigned ints in some ways?
Last edited on
Topic archived. No new replies allowed.