Why is this Loop Working Infinitely - c#

This is a simple while loop in C# but it is working infinitely.
int count = 1;
while (count < 10)
{
count = count++;
}
Why is this so?

The expression count++ returns the original value of count, then increments the value afterwards.
So you are overwriting count with the same value every time. Just do this:
count++;
For the curious, here's a link to Eric Lippert's article which distinguishes between operator precedence and the order of evaluation -- it's an interesting read:
http://blogs.msdn.com/b/ericlippert/archive/2009/08/10/precedence-vs-order-redux.aspx

This will loop infinitely.
There are two types of incrementing a variable:
Here count++ and ++count both are different if you have used ++count it will work.
Here count = count++ means count variable will be incremented by one then assigns the earlier value 1 to the count variable itself so count remains unchanged.

count = count++; does not increment count by one. x++ is the post increment operator, which means that the value returned by the expression is the old value. Thus, in your code, the following happens:
int oldValue = count;
count = count + 1;
count = oldValue;
What you probably meant to write was count++; (without the "count =").
More details about this can be found in the following SO question:
What does "count++" return in C#?

The ++ operator first saves the current value then increments and finally returns the saved value, so count will never change.
Eiter use the ++ operator or do an assignment. These are all equivalent:
count++;
count += 1;
count = count + 1;

count = count++;
This is a post-increment. It does the following.
int temp = count;
count++;
count = temp;
So you're not incrementing count. Use the following instead:
while (count < 10)
{
++count;
}

because
count++
returns count, not count + 1
just have count++ with no assignment or:
count = ++count;
the last one only to explain but you should not use it...
from: ++ Operator (C# Reference)
The first form is a prefix increment operation. The result of the
operation is the value of the operand after it has been incremented.
The second form is a postfix increment operation. The result of the
operation is the value of the operand before it has been incremented.
Numeric and enumeration types have predefined increment operators.
User-defined types can overload the ++ operator. Operations on
integral types are generally allowed on enumeration.

It is infinite because you aren't actually incrementing count.
count = count++; assigns the value of 1 to count and then increments count but since you don't assign the incremented value count never increases.
You need to do either:
count++;
or
count = ++count;

Let me ask you a question why do you make two operations on a single variable while one is enough?
what was your intention? count++ itself was enough so why again assign to count. May be you want to do something else.
You could have only count++, or ++count or count+1. I think other ways causes two operations.
Sorry for my way of writing.

Related

Why my integer number assignment is invalid?

This is my test code,it's very simple:
class Program
{
static void Main(string[] args)
{
int number = 0;
int newNumber = number++;
Console.WriteLine("the old number is {0},the new number is:{1}", number, newNumber);
Console.Read();
}
}
whereas the output result is:'the old number is 1,the new number is:0',I think it's opposite with the result I want.
using the postfix increment ++ operator, it first returns the original value, then increments. To get what you want use the prefix increment operator like
int newNumber = ++number;
But if you don't want to change number, don't use an incrementing operator, use addition/subtraction instead.
That is because number++ updates the value of number by incrementing it (PostFix). This is done after using the original value in the expression it is used. To achieve the desired behaviour, You can use:
int number = 0;
int newNumber = number + 1;
Here, you have used number++ which is Post increment operator.
It assigns the value first and then increments its value.
You can achieve your desired output in two ways :
Use Pre increment operator
int newNumber = ++number;
Simply adding 1 to number variable and then assigning it to newNumber
int newNumber = number + 1;

How to correctly iterate over all long type range

If I'd like to loop over all long's range, I would ingenually do:
for (long i = long.MinValue; i <= long.MaxValue; ++i)
{
// Do something
}
But it loops forever!
For example, if I do:
for (byte b = byte.MinValue; b <= byte.MaxValue; ++b)
{
// Do something
}
It loops forever too, but I solved like this:
for (int i = byte.MinValue; i <= byte.MaxValue; ++i)
{
byte b = Convert.ToByte(i);
// Do something
}
With long type how can I do?
With long type how can I achieve the same if I don't increment by 1, but of an higher distance?
Are those "ideas" to loop over a type range correct, are there some issues to be warned about, or can I do it better?
In your first two examples, the loop continues forever due to number range overflows.
When i (1st example) or b (2nd example) exceed the maximum value that can be stored in long (1st example) or byte (2nd example), their value overflows to the smallest value storable by that type and the loop starts over and over.
Remember: in a for-loop, first the loop condition is checked, then the counter increments. If the counter overflows during the increment, the subsequent loop condition check still evaluates to true.
To get your example working, try:
for (long i = long.MinValue; ; i++)
{
if (i == long.MaxValue)
{
break;
}
}
If you want to increment in larger steps, try:
const long step = 90000000000;
for (long i = long.MinValue; i <= long.MaxValue; )
{
// check if loop counter overflows when incrementing by the step
if (unchecked (i + step) < i)
{
break;
}
// otherwise it is safe to increment it
else
{
i += step;
}
}
This is caused by integer overflow when you try to increment past MaxValue. You could try this instead:
long i = long.MinValue;
do
{
// Do something
} while (i++ != long.MaxValue);
This way, the value of i is checked before it's incremented, and the loop terminates correctly.
You could use BigInteger to keep your loop pattern the same and avoid the overflow:
for (BigInteger i = long.MinValue; i <= long.MaxValue; ++i)
{
// Do something
}
I haven't benchmarked it, but I would imagine there would be a noticeable performance penalty for doing it this way.

Prefix and postfix increment in for loop

Given the following code
int j = 0;
for (int i = 0; i < str.Length; ++i) {
if (i==j) {
Console.WriteLine ("equal");
}
j++;
}
I expected that ++i would change i from initial 0 to 1 and thus i==j evaluated to false.
But it did not. Why?
If you have a loop in the form for (a; b; c) { d; }, you can treat this as the following while loop:
a;
while(b) {
d;
c;
}
As you can see, the increment doesn't occur until after the first iteration, regardless of whether it's a pre- or post- increment.
++i (or anything in the 3rd segment) will not be evaluated until after the first iteration.
No matter what though, even if it evaluated before your if, it would still not work the way you thought it did.
Doing i++ or ++i won't change anything because it would have been evaluated prior to it being used.
The true difference comes when you use it like so:
int i = 0;
if (i++ == 0) { /* True because the old value of "i" was used to compare */ }
i = 0;
if (++i == 0) { /* Not true because "i" got changed to 1 before the compare. */ }
i++ increments and evaluates to (i.e. results in, similar to returning) i's old value
++i increments and evaluates to i's new value
The statements i++; and ++i; are the same because you don't use the result, so the only important part is that they both increment i. Used in a for loop how you are, you're using them as standalone statements, you aren't using the values of the expressions i++/++i.
The compare is evaluated before the increment. Prefix or postfix makes no difference.

How is the 'e--' expression used in this simple exponent example?

I understand every cog in this code with the exception of one part: the "e--;" within the While loop. Can anybody explain its importance to me?
public class Power
{
public static void Main()
{
int e;
int result;
for(int i=0; i < 10; i++)
{
result = 1;
e = i;
while(e > 0)
{
result *= 2;
e--;
}
Console.WriteLine(string.Format("2 to the {0} power is {1}", i, result));
}
}
}
You're looking at a postfix decrement operator.
It evaluates the value of e and then subtracts one from the value; since it's a standalone statement, it simply subtracts one from e's value.
The idea here is to simply multiply result by 2 i times. It does this by setting e to i, subtracting one each iteration of the loop, and looping while it's positive. This means that the while loop will always loop i times. You could just as easily (and arguably more clearly) write:
for(int e = 0; e < i; e++)
result *= 2;
while(e > 0)
This means that your loop will run as long as e is greater than zero. e-- is decrementing e's value on each iteration. If you didn't decrement it inside of your loop then you will get an infinite loop because your condition will become always true and your loop won't end.
The e-- just decrements the value of e. It is equivalent to e = e - 1;.
The reason you decrement the value is to eventually exit of the while loop; once you set e to the value of i, the loop will run indefinitely unless the value of e becomes less or equal to zero, which makes the while loop condition of e > 0 false.
In the larger picture, you are using e to stored the current value of i and then use it to execute i times the statement result *= 2;. In other words, you are using e to count how many times the variable result needs to be multiplied by 2 during the current iteration of the outer for loop.
This is similar to doing something like,
for (int i=0; i < 10; i++)
{
result = 1;
e = 0;
for (e = i; e > 0; e--)
{
result *= 2;
}
}
Since the while loop is really acting as a for loop.
e is your counter variable. It will repeat the while loop until the result has been multiplied the specified number of times (which is whatever i is when the loop started). As others have stated, e-- just decrements the value of e by one. You can read more here. This means that, in the code you provided, it will multiply result by 2 e times which mathematically will compute 2^i (i.e. 2^0 = 1, 2^1 = 2, 2^2 = 4, etc.).
e-- means it will decrease 1 in each loop, e++ will increase 1
check this article http://msdn.microsoft.com/en-us/library/36x43w8w.aspx

multi-threaded increment and skip 0 without a lock?

I have a ushort counter (that occasionally rolls over). The messaging protocol that uses this value disallows a 0. I need some thread-safe way to increment this counter (stored in a class field) every time I read it, which isn't hard if I store it as an int and use the Interlocked.Increment. However, I'm not sure how to incorporate skipping 0 into that. It's okay if I occasionally skip a few numbers; my output sequence doesn't have to be perfect. I cannot ever reuse the same number in any block of 4000. I would like to avoid using a lock.
This one:
Given:
static int value = ushort.MaxValue;
And in the code:
int temp, temp2;
do
{
temp = value;
temp2 = temp == ushort.MaxValue ? 1 : temp + 1;
}
while (Interlocked.CompareExchange(ref value, temp2, temp) != temp);
You'll have to use an int and then cast it (for example in a get property), because the Interlocked aren't for all basic types.
We could probably make it a little faster in highly threaded contexts like this:
int temp = value;
while (true)
{
int temp2 = temp == ushort.MaxValue ? 1 : temp + 1;
int temp3 = Interlocked.CompareExchange(ref value, temp2, temp);
if (temp3 == temp)
{
break;
}
temp = temp3;
}
In this way we have to do one less read on failure.
As I've written in the comment, the central idea of this code is to increment in a temporary variable (temp2) the counter, and then trying to exchange the old value that we know with the new value (Interlocked.CompareExchange). If no one touched the old value in-between (Interlocked.CompareExchange() == temp) then we have finished. If someone else incremented the value then we do another try. The ushort is simulated by the use of an int with a fixed maximum value (temp == ushort.MaxValue ? 1 : temp + 1).
The second version, on failure of the Interlocked.CompareExchange() reuses the value read by the function as the new basis on which to add 1.
The Interlocked.CompareExchange used in that way can be used as a basis for building other Interlocked operations (you want an Interlocked.Multiply? You do a "standard" multiply and then try to Interlocked.CompareExchange the old value)

Categories

Resources