A little byte problem
BlitzMax Forums/BlitzMax Beginners Area/A little byte problem
| ||
Whats going on here? This code runs forever. Global b:byte For b=0 To 255 Print b Next It seems to be reseting back to 0 too soon. |
| ||
Very stange. |
| ||
Works fine on the Mac! Must be a bug in the x86 code... |
| ||
yep, runs forever on x86 version here too |
| ||
Well here it does count up to 255, but then it just starts over, much like what would happen in the following code:Global b:Byte = 0 While b < 256 Print b b:+1 End WhileInterestingly, this doesn't work either: Global s:Short For s = 0 To 65535 Print s Next |
| ||
yes it will only run up to 254 without the print get follow asm code look here _3: add byte [edx],1 _9: movzx eax,byte [edx] cmp eax,255 ! jle _5 ! _4: mov eax,0 jmp _6 _6: pop ebp ret |
| ||
Hehehehee bmx on x86 adds one to the variable and then checks to see if it is over the loop's count limit. By that time, the variable has reset to 0 ;] |
| ||
It's the same for regular integers. Apparently this bug was always in Blitz, but nobody noticed. I guess there's not much call for loops that go up to 2147483647. |
| ||
*EDIT* Working now .. see post below. This only prints 2,3,4,5 (missing the 1) ... framework brl.basic Local b:Byte For b=1 To 5 Print b next |
| ||
ive not come across this, and ive written a simple emulator that did 0-255.... oh wait.. there were no "bytes" in blitz.. so it would work with those values.. hmm... I must say, this is interesting. Mark, whats the plan? ^.^ |
| ||
ive not come across this, and ive written a simple emulator that did 0-255.... oh wait.. there were no "bytes" in blitz.. so it would work with those values.. hmm... I must say, this is interesting. Mark, whats the plan? ^.^ its okay for this to wrap forever as its understandable, (well, as a programmer used to 6502, 8 bit assembler) Global b:Byte = 0 While b < 256 Print b b:+1 End While however the following realy should work. maybe a simple clause will fix it in the compiler? i dont know. i know as much about Bmax's infrastructure as i do x86 assembly... hehehe. (nothing by the way) Global b:byte For b=0 To 255 Print b Next |
| ||
@JimB The 1 to 5 loop works here. Are you sure the 1 was missing? I've gotten seriously confused by apparently missing console output. Sometimes the window will scroll down even when the output is nowhere near the bottom. |
| ||
@jimb will work here framework brl.basic Local b:Byte For b=1 To 5 Print b next 1 2 3 4 5 |
| ||
yes it will only run up to 254 Huh? Runs up to 255 here...JimBs example also prints the one here. What kind of CPU's has everyone got? |
| ||
@Floyd, Mmmm, bizzare. it works now. Restarting the IDE (Win32 Beta) must have cured the output fault. @FD, CPU=Pentium 4 Mobile 3.06Ghz |
| ||
if you make it a local it works here, but global keeps looping?? CPU=3.2Ghz P4 |
| ||
if you make it a local it works here, but global keeps looping?? Yeah same here. Wierd that.CPU = 3.6 GHz Prescott. |
| ||
It kind of makes sense, because I bet globals are being written to memory and read in again, whereas the local version will be stored in a register pernamently. |
| ||
That's exactly what's happenning. |
| ||
My interpretation is this: Because you are asking for your loop variable to be a byte, and the biggest value you can store in a byte is 255, I think the For..Next loop perhaps adds 1 to the loop value PRIOR to testing to see if it is *greater than* the highest amount of the loop counter ie 255. So it would go something like this: Counter is at 253 Do the loop with counter at 253 Add 1 to the loop counter Is the counter>255? no, its 254, loop round Counter is at 254 Do the loop with counter at 254 Add 1 to the loop counter Is the counter >255 .... counter is now 255 but not >255, loop around Counter is at 255 Do the loop with counter at 255 Add 1 to the loop counter - should be 256 but 256 in binary is %100000000 and since the variable is only a byte, the `1` bit is ignored - it thinks counter=%00000000 Is the counter>255? ... should be yes but it only reads Counter as a byte which has gone beyond its numerical range, so Counter=0, keep looping and looping and loping forever because this keeps happening. That's my take on it. The loop counter is checking for a number greater than the loop limit, and adds the step to the counter at the END of each loop, BEFORE deciding whether to do another iteration. So if your loop limit is equal to the maximum number that can be stored in a variable of a given type (ie byte word long etc), there is an `overflow` that accidentally produces a value of 0 again, keeping the loop going. If this is true, you could *probably* test it by also doing a short/word sized loop, going from 0 to 65535, and when it reaches 65535 the counter should internally become %10000000000000000 (65536), even though only the lower 16-bits are recognized (=0). Maybe someone can test if this is the reason behind it. If so, maybe the Blitz developers need to come up with a fix to this design flaw. I am also expecting that when you define the Counter as a Local, it works, because Locals are kept in registers which are usually 32-bit, and I expect there is no difference in speed between comparing a byte value and comparing a long value, so it probably knows that the number reaches 256 instead of seeing it as 0? If this isn't exactly the reasoning behind it my second guess is perhaps the loop-counter value is held in an `immediate` value in assembly language, ie something like cmp #255,register, and really it needs to be a 16-bit compare in order to avoid the overflow problem? Feedback please. |
| ||
I am also expecting that when you define the Counter as a Local, it works, because Locals are kept in registers which are usually 32-bit, and I expect there is no difference in speed between comparing a byte value and comparing a long value, so it probably knows that the number reaches 256 instead of seeing it as 0? I'm thinking this sounds probable. |