• Advertisement
Sign in to follow this  

[C++] Counting down for-loop does not reach zero

This topic is 2307 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having a very strange error. I'm totally puzzled.

These are the two codes:

unSize is always 3.
uint64_t is the standard 64-bit unsigned integer type defined in stdint.h.
I copied the code as is, the other variables are irrelevant.



for (uint64_t i=unSize-1; i>=0; i--)
{
k_sum = 0.0;
for (uint64_t k=unSize-1; k>i; k--)
{
k_sum += U(i, k) * x(k, 0);
}
x(i, 0) = (y(i, 0) - k_sum) / U(i, i);
}

The only difference is, loop ending condition being "[color="#8b0000"]i>=0".
The variable i takes the values: 2, 1, 0, 18446744073709551615 (I believe this is unsigned equivalent of -1)



for (uint64_t i=unSize-1; i>0; i--)
{
k_sum = 0.0;
for (uint64_t k=unSize-1; k>i; k--)
{
k_sum += U(i, k) * x(k, 0);
}
x(i, 0) = (y(i, 0) - k_sum) / U(i, i);
}

The only difference is, loop ending condition being "[color="#8b0000"]i>0".
The variable i takes the values: 2, 1

Why doesn't the loop stop at i=0.
I just want the variable i to take the values 2, 1, 0.
How do I make it so that the final value of i in the final loop will be 0?

Share this post


Link to post
Share on other sites
Advertisement
I found my mistake. I want to write the fixed code for reference for other people.

The problem was that, an unsigned variable always has values equal to or greater than zero. So the ending condition "i>=0" does never happen.
I modified the code as below:

for (uint64_t i=unSize-1; (i>=0) && (i<unSize); i--)
{
k_sum = 0.0;
for (uint64_t k=unSize-1; k>i; k--)
{
k_sum += U(i, k) * x(k, 0);
}
x(i, 0) = (y(i, 0) - k_sum) / U(i, i);
}



This way, if variable i underflows and takes a very large value the loop will stop.

Share this post


Link to post
Share on other sites
Just a question about the logic of that for block. What's the difference between starting at zero and going to unSize - 1 vs starting at unSize - 1 and going to zero? I don't know what all those functions are doing, but I can't see why you have to have a decrementing loop rather than an incrementing loop.

Share this post


Link to post
Share on other sites

Just a question about the logic of that for block. What's the difference between starting at zero and going to unSize - 1 vs starting at unSize - 1 and going to zero? I don't know what all those functions are doing, but I can't see why you have to have a decrementing loop rather than an incrementing loop.


Because of the algorithm (a part of solution of linear matrix equation Ax=b), the loop must run backwards. Calculation of the matrix element x(i, 0) requires previous elements of x matrix (i.e.; x(i-1, 0), x(i-2, 0), x(i-3, 0), ..., x(0, 0)).

Share this post


Link to post
Share on other sites

[quote name='Cornstalks' timestamp='1320195358' post='4879473']
Just a question about the logic of that for block. What's the difference between starting at zero and going to unSize - 1 vs starting at unSize - 1 and going to zero? I don't know what all those functions are doing, but I can't see why you have to have a decrementing loop rather than an incrementing loop.


Because of the algorithm (a part of solution of linear matrix equation Ax=b), the loop must run backwards. Calculation of the matrix element x(i, 0) requires previous elements of x matrix (i.e.; x(i-1, 0), x(i-2, 0), x(i-3, 0), ..., x(0, 0)).
[/quote]
Ah, I see. Good old reverse substitution. Makes sense.

Share this post


Link to post
Share on other sites
A proper count-down unsigned loop:
for ( uint64_t i = unSize; i--; ) {
}


A proper signed count-down loop:
for ( int64_t i = inSize; --i >= 0; ) {
}


Counting down is guaranteed to be at least as fast and often faster than counting up, especially in Java.


L. Spiro

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement