Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
UBYTE/FOR loop issue?
#1
I wrote the following code to list out the numbers from 0 to 255:
Code:
DIM i as UBYTE = 0
for i = 0 to 255
    print i;"   "
next i

The code compiles and runs, but it never ends. When the loop gets to 255, it begins again from 0. :-)

Making the loop "0 to 254" or changing i to an INTEGER/UINTEGER gets around the issue.
Reply
#2
Well, this time it's not a bug, but a expected behaviour due to Ubyte overflow.
This question has already been answered here and previously here.

The problem comes because FOR a = 1 to 255 means "repeat until a > 255", since a is byte, that variable won't ever reach 256!.
This also happens in C and in other BASIC compilers. If you strinctly want to loop from 1 to 255 using uByte, use DO UNTIL looping statement:
Code:
Dim a as Ubyte = 0

Do
    LET a = a + 1
    PRINT a
Loop Until a = 255
Note, must use another PRINT before "Do" if you also want to print 0 (0 .. 255 => 256 times and so on.)
Reply
#3
Aha, I see - thanks for that. The thought had occurred to me that perhaps this was unavoidable, but it's nice to know for sure. Thanks for the info and the pointers!


While we're here and talking about types, could anyone tell me if there's a more elegant way to do this?

I have three UBYTES with values. I want to add them up, divide by three to get an average, and put the result into another UBYTE. However, I can't just do the maths with the UBYTES because the addition takes the value > 255 and information is lost.

I came up with this solution:
Code:
DIM x, y, z, q as UBYTE
DIM bigger as UINTEGER

x = 57
y = 127
z = 204

bigger = cast(UINTEGER, x)
bigger = (bigger + y + z) / 3
q = cast(UBYTE, bigger)
print q

... but it seems kind of messy. Is there a way to do that better?

I suppose the easiest way would be to store the three values as UINTEGERs to begin with and then cast to UBYTE at last minute, after the calculation?
Reply
#4
LTee Wrote:Aha, I see - thanks for that. The thought had occurred to me that perhaps this was unavoidable, but it's nice to know for sure. Thanks for the info and the pointers!

While we're here and talking about types, could anyone tell me if there's a more elegant way to do this?

I have three UBYTES with values. I want to add them up, divide by three to get an average, and put the result into another UBYTE. However, I can't just do the maths with the UBYTES because the addition takes the value > 255 and information is lost.

I came up with this solution:
[...] (Code)
... but it seems kind of messy. Is there a way to do that better?

I suppose the easiest way would be to store the three values as UINTEGERs to begin with and then cast to UBYTE at last minute, after the calculation?
It's this way, but you can use CAST(Uninteger...) dynamically:
Code:
DIM x, y, z, q as UBYTE

x = 57
y = 127
z = 204

q = (cast(Uinteger, x) + y + z) / 3
print q
That is, CAST(Uinteger, x) => Uinteger, so remaining parts wil be converted to uinteger automatically (always converted to the bigger type). You can also use CAST explicitly on y and z, but it's redundant here. Also, when storing the result into q, the type is enforced to be uByte back again. This is also the way C (and most traditional compilers) work. It's a rather advanced way, I think :oops: so you might prefer using cast explicitly on every type conversion instead of relaying on implicit ones.
Reply
#5
Aha, I see! I wasn't expecting C-like behaviour, to be honest - nice work! :-)

Thanks for the help!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)