Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using Hexadecimal numbers for array dimensioning and printing -what am I doing wrong?
#1
Hi all,
I have an old MCS BASIC-52 program that I want to run in QB64pe.  There is an external memory function XBY, that looks a lot like an array, so I wanted to preserve the hexadecimal addresses as much as possible.  However it seems that I have to use a suffix, even on hexadecimal numbers for them to either print or be used as an array index.  Yes, I could use the decimal equivalent but as these addresses represent IO points I wanted to keep as much hex as possible.  Is it understood or expected behaviour that you can't correctly print a 'long' hex number without a suffix?
This example is a little longer than it needs to be but I think you will get the point.  In the real code there is a lot of address (now array index) and content manipulation, so I would like to reduce the amount of suffixes I need to add and also limit the use of decimal number representation (if possible) 

Code: (Select All)
Dim XBY(&HE800~% To &HFFFF~%) As _Unsigned _Byte
Dim XBYD(59392 To 65635) As _Unsigned _Byte
Dim XBYFAIL(&HE800 To &HFFFF) As _Unsigned _Byte

E9 = &HE900~%: EA& = &HEA00: EB = &HEB00&: EF = &HEF00
XBY(&HE800~%) = 255: XBYD(59392) = 255
XBYFAIL(E9) = 255

Print &HE800~%, &HFFFF~%
Print &HE800, &HFFFF
Print 59392, 65635, E9, EA&, EB

Rem - typical line of code
Rem 3410 XBY(EA + PT) = 2 ^ B * (1 - UM)

Thanks
Reply
#2
Yes that is expected behavior and becomes clear when you look at it in binary:

E800 = 1110 1000 0000 0000

So as you see the leftmost bit, which is the sign bit, is set here, which makes E800 as is into a negative integer number. Now when you assign it to a long variable, then the compiler tries to preserve the negative nature of that number and makes it into:

FFFFE800 = 1111 1111 1111 1111 1110 1000 0000 0000

rather than:

0000E800 = 0000 0000 0000 0000 1110 1000 0000 0000

as you'd expect it.

You must use the ~% suffix to explicitly tell the compiler that your given integer E800 shall be a unsigned number. By the way, you might think that writing the entire long value 0000E800 instead, i.e. including the leading zeros could fix the problem, but it does not as almost all compilers I know usually ignore leading zeros before any numbers, hence even 0000E800 would need either need the ~% or ~& suffix.



The whole thing only happens for numbers which have the sign bit set, i.e. 0000-7FFF should just work fine, while 8000-FFFF naturally are negative numbers and require the unsigned integer suffix.

The same thing would happen again at the long to integer64 boundary, i.e. when writing a long hex value but assigning it to a integer64 variable, then 00000000-7FFFFFFF would be ok as is, while 80000000-FFFFFFFF would need the unsigned long (~&) suffix to make the values unsigned.

There's no way around, that's simply how the binary system works.
Reply
#3
XBYFAIL has a negative index range.
Not a problem in itself.
If you define E9 also negative  E9 = &HE900   then all is fine
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#4
(08-13-2024, 03:55 PM)mdijkens Wrote: XBYFAIL has a negative index range.
Not a problem in itself.
If you define E9 also negative  E9 = &HE900   then all is fine
 Thanks for the suggestion, but the range is smaller and the program does arithmetic on the index (and the index has a physical meaning).

 Perhaps this page needs a little more detail in the example:

Code: (Select All)
a& = &HC0DEBA5E 

https://qb64phoenix.com/qb64wiki/index.php/%26H

I understand what's happening.  I maybe just need to define more of the variables explicitly
Reply
#5
Just for reference:

Code: (Select All)
Dim B As _Unsigned Integer
a& = &HC0DEBA5E
B = &HFFFF
Print a&, B
Reply




Users browsing this thread: 4 Guest(s)