![]() |
Forum Index : Microcontroller and PC projects : mm2 Newbie Variable Questions
![]() ![]() |
|||||
Author | Message | ||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
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: AustraliaPosts: 6283 |
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: AustraliaPosts: 1114 |
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: AustraliaPosts: 582 |
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: AustraliaPosts: 6283 |
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 KingdomPosts: 4044 |
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 KingdomPosts: 2170 |
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: AustraliaPosts: 582 |
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. 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: AustraliaPosts: 114 |
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 KingdomPosts: 4044 |
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 KingdomPosts: 10315 |
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: AustraliaPosts: 582 |
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 KingdomPosts: 10315 |
You don't need a synopsis - just the manual 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" |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |