Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 22:59 20 Apr 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMBasic - Odd behaviour OR I've lost the plot

Author Message
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 01:40pm 22 Sep 2020
Copy link to clipboard 
Print this post

Away from the CMM2 today and coding a class via MMBasic (DOS).

Created a function to convert a decimal to a binary (8 bit) number.   The function works fine when called individually -- binary(10) for example.  But when I wrap the function in a For/Next loop -- say I want to print all the binary from a to b -- it fails, with some odd behaviour.

Happy to acknowledge the issue is probably my code -- but after dropping this into class and testing it --- no idea why.

Any insight greatly recieved:

Function binary(x) As string

   'astr$ assembles the binary representation, in reverse

   Local astr$= Str$(x Mod 2) ' intial value
   Local rev$=""  'define the reversed string
   Local pad = 0  'the padding to make up to 8 bits


    Do
       If x Mod 2 = 1 Then  ' ie if there is a remainder
           x = x \ 2  'divide and round down
       Else
           x = x / 2  ' actual division
       End If

       astr$ = astr$ + Str$(x Mod 2)  ' assemble a string of the bits

   Loop While x <> 0

   pad=8-Len(astr$)   ' pad it out to 8 bits

   For n = 1 To pad
       astr$=astr$+"0"
   Next n

   For i = 8 To 1 Step -1
       rev$=rev$+Mid$(astr$,i,1)  ' reverse the string so it reads left to right
   Next i

   binary$=(rev$)  'dump rev$ into binary$ so that the function returns it

End Function

''Test the function

Print "Binary of 10 = " binary(10)  'test the function  - should produce 00001010  (ie 2^3 + 2^1 = 8 + 2 = 10)
Print "Binary of 128 = " binary(128) 'test - should produce 10000000

x = 11

Print "Binary of " x " = " binary(x)  ' passing x as a variable produces the right answer


''' works as expected until here...........


'' but when I wrap the function in a loop, all hell breaks lose.....
'' uncomment for fun

Print ""
For x = 8 To 16   'arbitary range to convert from decimal to binary
  'Print "Binary of " x " = " binary(x)    '' if you uncomment this and observe ????
  Print x    '' if you leave the above line commented, but uncomment this >> loop clearly working
Next x

Entropy is not what it used to be
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3833
Posted: 01:44pm 22 Sep 2020
Copy link to clipboard 
Print this post

I had the briefest of looks, but:

Variables are passed by reference, so in your code a call to binary(x) actually changes the value of x in the caller.

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8570
Posted: 01:45pm 22 Sep 2020
Copy link to clipboard 
Print this post

Variables are passed by reference in MMBasic. Take a local copy in the function and only change the copy
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 01:46pm 22 Sep 2020
Copy link to clipboard 
Print this post

  thwill said  I had the briefest of looks, but:

Variables are passed by reference, so in your code a call to binary(x) actually changes the value of x in the caller.

Tom


OK - get that.

So how do I programmatically call the function inside a loop ?

Sorry if I'm being dense.
Nim
Entropy is not what it used to be
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 01:46pm 22 Sep 2020
Copy link to clipboard 
Print this post

  matherp said  Variables are passed by reference in MMBasic. Take a local copy in the function and only change the copy


Got it -- I think.

Off for a play.. (ie serious tweaking)

Many thanks

Nim
Entropy is not what it used to be
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 01:51pm 22 Sep 2020
Copy link to clipboard 
Print this post

Solved....

Changing references to x in the function to "num" and defining "num" as "Local num = x" solved it.

Thank you!!!

Nim
Entropy is not what it used to be
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1985
Posted: 04:08pm 22 Sep 2020
Copy link to clipboard 
Print this post

Evening Nim

probably missing something - is the idea of the above code to teach *how* to do this or to end up with a binary representation of you number

Don't want to go down the Bin$(x,8) route without giving you due credit.

h
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 07:02pm 22 Sep 2020
Copy link to clipboard 
Print this post

  CaptainBoing said  Evening Nim

probably missing something - is the idea of the above code to teach *how* to do this or to end up with a binary representation of you number

Don't want to go down the Bin$(x,8) route without giving you due credit.

h


Good question.

I am teaching a group of students using the CMM2.  We are making a reusable library of "functions" - so to answer your Q - its about teaching how to do this, not actually converting from decimal to binary.  My example was more about the behaviour of the code, which turned out to be about passing by reference not value (which I sorted now).


As an extension, they are trying to figure out how to convert from any base (including negative bases) into any other base.  As in baseconv(15,2,3)  --> in this case -- convert 15 in base 2 to 15 in base 3 --> needless to say they are no where near this level of sophistication yet.  Some interesting math when you use negative bases.

Cheers
Nim
Entropy is not what it used to be
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 07:06pm 22 Sep 2020
Copy link to clipboard 
Print this post

  Nimue said  
  CaptainBoing said  Evening Nim


Don't want to go down the Bin$(x,8) route without giving you due credit.

Nim


That said, I was unaware Bin$(x,8) existed --- at the risk of starting another forum meltdown, I tend to veer towards "big P" as my goto code --- that was until I discovered the CMM2.

Nim
Entropy is not what it used to be
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5886
Posted: 10:50pm 22 Sep 2020
Copy link to clipboard 
Print this post

Just to add more confusion to the mix.
Normally MMBasic complains if you define a variable with the same name but different type.
You can do this within a sub or function because it is local.
But when it comes to passing byref, things can get interesting.
 OPTION EXPLICIT
 DIM INTEGER s = 1245
 DIM INTEGER k = 1245
 
 PRINT "Same 'name' but different types"
 PRINT mytest(s)
 PRINT s
 PRINT
 PRINT "Same 'name' and same types = byref"
 s = 1245
 PRINT mytest2(s)
 PRINT s
   PRINT
 PRINT "Different 'name' and same types = byref"
 k = 1245
 PRINT mytest2(k)
 PRINT k
 
FUNCTION mytest(s AS FLOAT)
 s = s/2
 mytest = s
END FUNCTION
 
FUNCTION mytest2(s AS INTEGER)
 s = s/2
 mytest2 = s
END FUNCTION


It will catch you out if you are not using OPTION DEFAULT NONE and end up with floats by default then declare an INTEGER.

Jim
VK7JH
MMedit   MMBasic Help
 
capsikin
Guru

Joined: 30/06/2020
Location: Australia
Posts: 341
Posted: 12:44am 23 Sep 2020
Copy link to clipboard 
Print this post

I didn't know you could refer to a string function called binary as binary$ (when you set its return value). When I've done that sort of thing with variables it gave an error, and it seems clearer to either always use or always omit the $.
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3649
Posted: 01:33pm 24 Sep 2020
Copy link to clipboard 
Print this post

A thought in passing:

      If x Mod 2 = 1 Then  ' ie if there is a remainder
          x = x \ 2  'divide and round down
      Else
          x = x / 2  ' actual division
      End If


Can probably just be

      x = x \ 2


John
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 02:30pm 24 Sep 2020
Copy link to clipboard 
Print this post

  JohnS said  A thought in passing:

      If x Mod 2 = 1 Then  ' ie if there is a remainder
          x = x \ 2  'divide and round down
      Else
          x = x / 2  ' actual division
      End If


Can probably just be

      x = x \ 2


John


Nice stop -- to be fair, I was more focused on be overly explicit with the kiddos, but also in fairness, missed that one.

Cheers
Nim
Entropy is not what it used to be
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3649
Posted: 02:38pm 24 Sep 2020
Copy link to clipboard 
Print this post

Might be interesting to see if any of the kids spot it...

John
 
Womble

Senior Member

Joined: 09/07/2020
Location: United Kingdom
Posts: 267
Posted: 03:02pm 24 Sep 2020
Copy link to clipboard 
Print this post

  JohnS said  Might be interesting to see if any of the kids spot it...
John

Thats evil John

I didn't until I thought about it and checked the operator list in the manual
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 03:17pm 24 Sep 2020
Copy link to clipboard 
Print this post

  Womble said  
  JohnS said  Might be interesting to see if any of the kids spot it...
John

Thats evil John

I didn't until I thought about it and checked the operator list in the manual


/ vs \ is really quite an interesting teaching point.

Many learners use them interchangeably when "doing math" -- ie

13 / 3 =    compared with 13 \ 3 = many teachers don't pick up the difference as many don't realise there is symbolically quite a difference.

One lovely thing of the CMM2 it that it give me an excuse to teach this stuff....

Nim
Entropy is not what it used to be
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5886
Posted: 08:55pm 24 Sep 2020
Copy link to clipboard 
Print this post

  Nimue said  

/ vs \ is really quite an interesting teaching point.

Many learners use them interchangeably when "doing math" -- ie

13 / 3 =    compared with 13 \ 3 = many teachers don't pick up the difference as many don't realise there is symbolically quite a difference.

One lovely thing of the CMM2 it that it give me an excuse to teach this stuff....

Nim


Try adding INT FIX and CINT into the mix.
Integer division is not the same as INT for negative numbers
\ rounds towards zero, not down.

DIM FLOAT x

FOR x = -5  TO 5
div x
NEXT x
END

SUB div(x)
PRINT
PRINT "x         ";x
PRINT "x/2       ";x/2
PRINT "x\2       ";x\2
PRINT "fix(x/2)  ";FIX(x/2)
PRINT "int(x/2)  ";INT(x/2)
PRINT "cint(x/2) ";CINT(x/2)
END SUB


Jim
VK7JH
MMedit   MMBasic Help
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5886
Posted: 11:22pm 24 Sep 2020
Copy link to clipboard 
Print this post

This is a better example of the differences (and pitfalls)
DIM FLOAT n,k
DIM INTEGER m
PRINT "N   INT(N) CINT(N) FIX(N)  n\1  k\2   m"
FOR n = -3 TO 3 STEP 0.25
m = n ' assign a float to an integer
k = n * 2
PRINT STR$(n,2,2),,INT(n),,CINT(n),,FIX(n),,n\1,,k\2,,m
NEXT n


N  INT(N) CINT(N) FIX(N) n\1  k\2  m
-3.00 -3 -3 -3 -3 -3 -3
-2.75 -3 -3 -2 -3 -3 -3
-2.50 -3 -3 -2 -3 -2 -3
-2.25 -3 -2 -2 -2 -2 -2
-2.00 -2 -2 -2 -2 -2 -2
-1.75 -2 -2 -1 -2 -2 -2
-1.50 -2 -2 -1 -2 -1 -2
-1.25 -2 -1 -1 -1 -1 -1
-1.00 -1 -1 -1 -1 -1 -1
-0.75 -1 -1 0 -1 -1 -1
-0.50 -1 -1 0 -1 0 -1
-0.25 -1 0 0 0 0 0
0.00 0 0 0 0 0 0
0.25 0 0 0 0 0 0
0.50 0 1 0 1 0 1
0.75 0 1 0 1 1 1
1.00 1 1 1 1 1 1
1.25 1 1 1 1 1 1
1.50 1 2 1 2 1 2
1.75 1 2 1 2 2 2
2.00 2 2 2 2 2 2
2.25 2 2 2 2 2 2
2.50 2 3 2 3 2 3
2.75 2 3 2 3 3 3
3.00 3 3 3 3 3 3


It aligns better on screen.

Between the floating point rounding and different methods, life gets 'interesting'

Jim
VK7JH
MMedit   MMBasic Help
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024