...

View Full Version : Increment var by 1 in loop



dprichard
04-06-2009, 04:26 PM
I have a loop that is running and I am trying to increment a number by one each time. Here is what I am doing, but each time it just writes out 1 for the value.

var i=1;

Start of Loop

document.write(i);

var i=i++;

End of loop

It just writes out 1 each time though. Any help would be greatly appreciated.

Eldarrion
04-06-2009, 04:52 PM
Where are you assigning the variable? If you are calling a function that executes the loop and it is done like so:



function loop() {
var i = 1;
// loop begins
document.write(i);
i++;
// loop ends.
}


Your variable (i) will always start at 1. Try pulling it out of the function and see how that works for you... of course, in that case, it will have to be turned into a global variable, rather than a local one, but eh... you get the idea. In addition... what are the conditions of your loop? Does it run more than once? And well... there's the thing that executing document.write on a finished page will replace everything in the page (Including the JavaScript that does the loop). I tried it with the following JS and it seemed to work just fine:



<script type="text/javascript">
loopy = 1;
function testloop() {
for (var i=1;i < 3;i++) {
loopy++;
alert(loopy);
}
}
</script>


By fine, I mean that every time you go through the loop, you get 2 alerts and the variable increments by 1 in each.

Old Pedant
04-06-2009, 08:45 PM
Eldarrion missed the important BUG that you have created!!!

First of all, you have *TWO* variables name i. One outside the loop, one inside. That, in itself, is surely an error. But it's not the cause of your bug.

You have to understand how assignment interacts with the expression on the right side of the equals sign.

When you code

i = i++

(and, yes, the "var" there is irrelevant, except that it creates a second variable named i)
you have to read that thus:
(a) pick up the current value of i; that will be the value of the expression on the right side of the equals. The first time through the loop, the value is 1, so that is the value of the expression on the right side of the equals sign.
(b) *THEN* increment i. So if i was 1, it is now 2.
(c) *THEN* assign the value of the expression to the variable on the left of the equals sign. As noted in (a), that value is 1. So you just assigned 1 to i.
(d) pick up the current value of i; that will be the value of the expression on the right side of the equals. as noted in (c) and (f) that value is 1.
(e) *THEN* increment i. So if i was 1, it is now 2.
(f) *THEN* assign the value of the expression to the variable on the left of the equals sign. As noted in (a), that value is 1. So you just assigned 1 to i.
(g) loop back to (d).

So, indeed, the loop and the variable are working correctly AS YOU CODED IT!

Now keep it simpler:


var i = 1
[start of loop]
++i; // or you can use i++ (same effect if in a statement by itself)
[end of loop]

voila! it works.

dprichard
04-06-2009, 08:50 PM
Awesome, that worked perfectly.

Thank you!!!!!!

Old Pedant
04-06-2009, 08:59 PM
It's all because of the peculiarities of the post-increment (and post-decrement) operator.

It's just one reason I tend to avoid the post-xxx operators unless I determine a real need for them. It's also true that more than likely the pre-xxx operators are mildly more efficient.

After all, for the post-xxx operators, the JS interpreter has to have logic something like this:

push value of i on stack
push value of i on stack
push constant 1 on stack
add [adds two values on top of stack and puts sum back on stack]
store top of stack into i
pop value on top of stack [to get back the original value of i]

The pre-increment operator is simpler:


push value of i on stack
push constant 1 on stack
add [adds two values on top of stack and puts sum back on stack]
store top of stack into i [without a pop]

There are surely some efficiencies that can be put in there, so it depends on how smart the JS interpreter you are using is, but the idea is the same: The original value has to be held somewhere, temporarily, while the increment-and-store takes place. Not so with the pre-increment.

On one C compiler I wrote the code generator for--on a VERY limited (8-bit) CPU--I actually implement it thus:


get value of i to register
increment register
store result in i
decrement register (back to original value, which is needed value for other ops)

Hacky, but more efficient than the double push on stack stuff.

Even modern compilers (e.g., C++) have to do something like:


get value of i to register A
copy value to register B
increment register A
save register A to i
(then use register B in subsequent ops)

So one more machine level instruction than when you use a pre-increment operator.
Smart compilers will skip the copy-to-B when the realize that you aren't going to do anything with the value (e.g., when the statement is standalone, not part of any other expression).



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum