Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 05:29 02 Aug 2025 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 : mm2 Newbie Variable Questions

     Page 2 of 2    
Author Message
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 11:27pm 17 Jul 2020
Copy link to clipboard 
Print this post

  TassyJim said  MMBasic uses signed integers

64 bit signed integers are 63 bits plus sign bit

That give you +-9.22x10^18



very true.

Remember the sign is only shown when expressing them as decimals.

When converting to Hex, Oct or Bin, you get an implicit positive because you get a literal expression of the bytes that make up the integer so it is down to you how you want to interpret it.

Stumbled into this a bit with my timer extensions (AFTER, EVERY) where I use the top two bits of a variable to store the type of counter. Code like
TMRini(Tmr)=Interval OR &h8000000000000000

just didn't feel right (or look it) as
...OR -9223372036854775808

let alone being clear what I am doing

my 2p
Edited 2020-07-18 09:30 by CaptainBoing
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 01:53am 18 Jul 2020
Copy link to clipboard 
Print this post

  zeitfest said  
What happens when the most significant bit is set, in MM ? Is the whole value used as a positive number ?

Look up about 2's complement integers

Or try this simple program to see it in action
dim integer n
for n = 10 to -10 step -1
print bin$(n,64);" ";n
next n


0000000000000000000000000000000000000000000000000000000000001010  10
0000000000000000000000000000000000000000000000000000000000001001  9
0000000000000000000000000000000000000000000000000000000000001000  8
0000000000000000000000000000000000000000000000000000000000000111  7
0000000000000000000000000000000000000000000000000000000000000110  6
0000000000000000000000000000000000000000000000000000000000000101  5
0000000000000000000000000000000000000000000000000000000000000100  4
0000000000000000000000000000000000000000000000000000000000000011  3
0000000000000000000000000000000000000000000000000000000000000010  2
0000000000000000000000000000000000000000000000000000000000000001  1
0000000000000000000000000000000000000000000000000000000000000000  0
1111111111111111111111111111111111111111111111111111111111111111 -1
1111111111111111111111111111111111111111111111111111111111111110 -2
1111111111111111111111111111111111111111111111111111111111111101 -3
1111111111111111111111111111111111111111111111111111111111111100 -4
1111111111111111111111111111111111111111111111111111111111111011 -5
1111111111111111111111111111111111111111111111111111111111111010 -6
1111111111111111111111111111111111111111111111111111111111111001 -7
1111111111111111111111111111111111111111111111111111111111111000 -8
1111111111111111111111111111111111111111111111111111111111110111 -9
1111111111111111111111111111111111111111111111111111111111110110 -10
>


Jim
VK7JH
MMedit
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1114
Posted: 02:10am 18 Jul 2020
Copy link to clipboard 
Print this post

Interestingly, on the CMM2 for floats, of the three ways of indicating variable type,

1.  using DIM,
eg.

DIM a as float
a =  a + 1
... and so on

2.  using type indicator ! only (no DIM)
eg.

a! = a! + 1
... and so on

3.  or using both DIM and type indicator !,
eg.

DIM a as float
a! = a! + 1
... and so on


Without OPTION EXPLICIT ON then the third way, using both DIM and a type indicator, is around 1 percent the fastest.

With OPTION EXPLICIT ON (highly recommended by most), example 2 is no longer possible and example 3 still appears to be faster by around 1 percent.

As a matter of ease of use for me personally, I use OPTION EXPLICIT ON and the third method (both DIM and type indicator) purely because when perusing/developing code, I can see by the type indicators exactly what type the variable is.

Doug.
Edited 2020-07-18 12:14 by panky
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 582
Posted: 03:58am 18 Jul 2020
Copy link to clipboard 
Print this post

  Quote  "64-bit unsigned numbers can be created using the &H, &O or &B prefixes to a number and these numbers can
be stored in an integer variable."


Obviously the full 64-bit binary field can be created and filled, but if the most significant bit is set then any math will treat the number as a negative integer.
So I do not see how anyone can create/use an ordinary 64-bit unsigned (positive decimal) integer in MM, ie values over 2^63.

Granted, it is not a common useage, but it is not an ignorant question.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 04:43am 18 Jul 2020
Copy link to clipboard 
Print this post

  zeitfest said  
So I do not see how anyone can create/use an ordinary 64-bit unsigned (positive decimal) integer in MM, ie values over 2^63.

Granted, it is not a common useage, but it is not an ignorant question.


Consider the DS18B20 temperature module.
It has a 64 bit device/serial number.
If you want to have more than one of them connected to the same pin, you need to store and use the serial number so you can address each one individually.
Rather than storing it as 8 bytes, it is very convenient to store it in a single 64 bit variable.

This is a common use for variables where the actual perceived value is not important.

We can do bit manipulation such as AND OR and XOR without any fear.

Just don't try and think of it as a number.

(Someone will probably point out that the DS18B20 will never have a 64bit serial with the top bit set but it serves to make the point)

Jim
VK7JH
MMedit
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 06:57am 18 Jul 2020
Copy link to clipboard 
Print this post

  zeitfest said  
  Quote  "64-bit unsigned numbers can be created using the &H, &O or &B prefixes to a number and these numbers can
be stored in an integer variable."


Obviously the full 64-bit binary field can be created and filled, but if the most significant bit is set then any math will treat the number as a negative integer.
So I do not see how anyone can create/use an ordinary 64-bit unsigned (positive decimal) integer in MM, ie values over 2^63.

Granted, it is not a common useage, but it is not an ignorant question.


As has been posted, read up on twos complement.  And then... you have to get your head around what it means: you can regard a stored value as a range of signed numbers or as a (different) range of unsigned numbers.

The math operations work the same (see NOTE) in the two ways of thinking about the stored bit pattern - it's why so many CPUs use 2s complement.

It can be somewhat mind-boggling until you get used to it.

However, various parts of a language (in this case MMBasic) may choose to favour one of the two ways of thinking of the pattern.  E.g.
PRINT i ' with i an INTEGER
treats i as signed.  But i is no more signed than unsigned, it's just PRINT choosing which way to print it out.

NOTE unless the CPU / language checks for and takes action on overflow/underflow, which MMBasic does not (C also does not)

John
Edited 2020-07-18 16:59 by JohnS
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 07:59am 18 Jul 2020
Copy link to clipboard 
Print this post

If two's compliment is "new", to explore I would highly recommend playing with it in byte-wide format with a paper and pencil just so you don't tie your brain in a knot. The principals are the same regardless of the bit-count but it is a lot easier to handle. Then to take it to any number of bytes you just Sign Extend to fill all the bits to the left, e.g. to convert a signed 7 bit number to a signed 63 bit number, just take the leftmost bit and copy it to all bits to the left of the "number part"

I wrote a function to do this to get a signed number of less than 63 bits to play nicely as an MMBasic integer

http://www.fruitoftheshed.com/MMBasic.Sign-Extend-an-Integer.ashx
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 582
Posted: 09:23am 18 Jul 2020
Copy link to clipboard 
Print this post

It is hardly "new" to me. I wrote a 64-bit math library for 16 bit micros, in assembler, and proved the accuracy of the results.

The question is specifically about 64-bit unsigned (positive decimal) integers in MM, ie values over 2^63.


That is, values over 2^63.

Did I say, values over 2^63 ?

Gosh, what I meant was, values over 2^63.

In other words, values over 2^63.

You know, like, values over 2^63.

Actually, values over 2^63.

Oh dear, there may have been a misprint, I meant values over 2^63.

Not values under or at 2^63....values over 2^63.

Blue Stilton values over 2^63.

Dead Parrot values over 2^63.

Really, like, whatever, values over 2^63.

"You're soaking in it" values over 2^63.




  Quote  "64-bit unsigned numbers can be created using the &H, &O or &B prefixes to a number and these numbers can
be stored in an integer variable."



So you can fill in all 64 bits [ 18,446,744,073,709,551,616 ] and store that in an integer variable but MM will almost certainly not treat that as corresponding to an unsigned 64 bit integer.

If someone can do something like

dim integer n
n = 18000000000000000000
print n

and get a sensible result without dropping into binary formats, please post it.

I am leaving it at that.
 
flip
Senior Member

Joined: 18/07/2016
Location: Australia
Posts: 114
Posted: 09:26am 18 Jul 2020
Copy link to clipboard 
Print this post

Hi all,
At risk of confusion further, the simple way I think of it is that Integers are stored exactly the same way irrespective of whether our brain thinks of it as signed or unsigned.
'Largest possible +ve 2's complement integer possible with signed 64 bit
> a%= 2^62 + 2^62 - 1
> ? a%
9223372036854775807
> ?hex$(a%)
7FFFFFFFFFFFFFFF
'Now increment it
> a% = a% + 1
> ?hex$(a%)
8000000000000000
> ? a%
-9223372036854775808

Above shows two representations of same number
The hex value could be thought of as unsigned 64-bit representation of the number
Its 2^63 (same as 2^62+2^62 -1 +1)
MSB is set
However printing a% gives a negative number

IIRC The bounds checking has been deliberately left out to allow 64-bit processing (yes even addition and subtraction all work correctly whether we think of the number as 64 bit signed or 64-bit unsigned...HOWEVER we (as coders) need to fully understand and implement bounds checking (whenever using these extremities of operation) because there is no bounds checking implemented on these Most-significant-bit MSB rollovers in MMBASIC. Two's complement allows all numbers to live in a linear manner, so when subtracting 1 from 0, the value is understood to be -1, but for a computer it becomes all ones (FFFFFFFFFFFFFFFF for a 64-bit data integer element)
I'd recommend looking for articles on digital logic at how Adders work for the full detail, as I'm sure it will be clearer than the above attempt.

Regards Phil
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 09:52am 18 Jul 2020
Copy link to clipboard 
Print this post

  zeitfest said  So you can fill in all 64 bits [ 18,446,744,073,709,551,616 ] and store that in an integer variable but MM will almost certainly not treat that as corresponding to an unsigned 64 bit integer.


MM will do math on it as if it's an unsigned 64-bit integer.

It favours representations in decimal for source code, printing, etc as signed.

That's a benefit of twos complement.

Your way of phrasing it makes it sound untrue, however.

I think MMBasic is missing the "u" notation C has, but could readily add it - that's where you would write (perhaps)

dim integer n
n = &u18000000000000000000

You'd need a corresponding format.

Nothing else needs changing, as twos complement is already in use internally in the CPU.

I'm somewhat puzzled in that one moment you sound like you understand this and the next that you don't.

John
Edited 2020-07-18 19:53 by JohnS
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 10:31am 18 Jul 2020
Copy link to clipboard 
Print this post

Page 23 of the CMM2 manual is explicit in what can and can't be done with unsigned - simples!
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 582
Posted: 01:19pm 18 Jul 2020
Copy link to clipboard 
Print this post

The synopsis I have, from all of that, is :

a) MMBasic does not formally have unsigned integer datatypes.
b) It is possible to create bit sequences of 64 bits using low level bit field addition/masking operations, and handle and store them as per signed integers.
c) They can be processed with normal twos-complement arithmetic, but without bounds checking.
d) MMBasic does not have a decimal input statement format (that can accurately assign to memory) an ordinary decimal integer magnitude over 2^23.
e) MMBasic does not have a decimal output statement that will produce an ordinary decimal integer magnitude over 2^23.
f) Using say, a print statement to output or display a positive decimal value over 2^23 will produce an incorrect negative number as the print format conversion maths will assume the number is a signed integer using bit 64 for sign information.
g) Page 23 of the CMM2 manual no doubt has more detailed description, however the original post enquiries were citing a different text.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 01:58pm 18 Jul 2020
Copy link to clipboard 
Print this post

  Quote  The synopsis I have, from all of that, is :


You don't need a synopsis - just the manual

  Quote  64-bit Unsigned Integers
MMBasic on the Colour Maximite 2 supports 64-bit signed integers.  This means that there are 63 bits for holding the number and one bit (the most significant bit) which is used to indicate the sign (positive or negative).  However it is possible to use full 64-bit unsigned numbers as long as you do not do any arithmetic on the numbers.
64-bit unsigned numbers can be created using the &H, &O or &B prefixes to a number and these numbers can be stored in an integer variable.  You then have a limited range of operations that you can perform on these.  They are << (shift left), >> (shift right), AND (bitwise and), OR (bitwise or), XOR (bitwise exclusive or), INV (bitwise inversion), = (equal to) and <> (not equal to).  Arithmetic operators such as +, -, etc may be confused by a 64-bit unsigned number and could return nonsense results.
Note that shift right is a signed operation.  This means that if the top bit is a one (a negative signed number) and you shift right then it will shift in ones to maintain the sign.
To display 64-bit unsigned numbers you should use the HEX$(), OCT$() or BIN$() functions.
For example, the following 64-bit unsigned operation will return the expected results:
X% = &HFFFF0000FFFF0044
Y% = &H800FFFFFFFFFFFFF
X% = X% AND Y%
PRINT HEX$(X%, 16)
Will display "800F0000FFFF0044"
 
     Page 2 of 2    
Print this page


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

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025