How to convert hexadecimal characters back in MSX basic

Page 3/3
1 | 2 |

By gdx

Enlighted (5035)

gdx's picture

14-01-2022, 15:18

Parn wrote:

an hexadecimal number on MSX-BASIC is always an integer. Integer numbers in MSX-BASIC range from -32768 to 32767 (or &H8000 to &H7FFF, if you prefer). Statements like POKE and functions like PEEK accept any number in the range from -32768 to 65535, so naturally if you want to use numbers larger than 32767 with those statements and functions you must use another number type. If you mix and match number types you are bound to stumble on unpredicted behaviour.

I know. The folowing lines return the same SIGNED VALUE as i precised above.

L#=&HC000: PRINT L#
L!=&HC000: PRINT L!
L%=&HC000: PRINT L%

but this is not the case with PEEK(&HF673)*256+PEEK(&HF672) because it return an non signed value (and that is superior to an integer value in my example). That was the reason for my post. This was to show that, to my knowledge, you cannot directly convert a hex value to an unsigned value. So I was wondering how do to get examples.

pizzapower wrote:

But you are doing this:

20 FOR M#=A% TO B#

This is not a problem and in any case not the one I wanted to highlight. I pointed out that an hex value is take as a SIGNED VALUE and it is not possible to interpret it as NON SIGNED VALUE.

pizzapower wrote:

There is no actual problem here just because you think that an address must only be represented by hexadecimal numbers.

No. I think it's a pity that hexadecimal numbers can not be converted to non signed value because that would simplify the addresses handling.

Am I clear enough now?

pgimeno wrote:

The wiki's wording was pretty misleading. I've edited it.

Thanks. It's more understandable now.

By pizzapower

Resident (42)

pizzapower's picture

14-01-2022, 18:30

gdx wrote:

I know. The folowing lines return the same SIGNED VALUE as i precised above.

L#=&HC000: PRINT L#
L!=&HC000: PRINT L!
L%=&HC000: PRINT L%

In the first two you are only converting integers to double and single, since all (integer) numerical notations mean nothing underneath the tokenized source code. You might as well type:

L# = -16384%
L! = -16384%

Same thing. Although there is a data type mismatch, BASIC doesn't complain and converts it silently (coercion) since it fits nicely. But there are several reasons why hexadecimal notation is bound to integer, and one of them is because of boolean bitwise operations. Have you tried to AND 65535 with 1? You get an overflow because it must convert to integer first.

Another reason why hexadecimal is bound to integer is because of precision. What would you expect to get by ANDing 1000001! with 1 if you could get away with it? The least significant bit is completely lost due to lack of precision. Imagine if BASIC would let the user shoot oneself in the foot by allowing this kind of behaviour. Poking the wrong address could halt the machine and it would be very hard to detect the problem.

gdx wrote:
pizzapower wrote:

But you are doing this:

20 FOR M#=A% TO B#

This is not a problem and in any case not the one I wanted to highlight. I pointed out that an hex value is take as a SIGNED VALUE and it is not possible to interpret it as NON SIGNED VALUE.

Because the real problem goes much deeper than that, as I stated above. You must understand that VALUE has a data type attached to it. Always. A more complex BASIC just to deal with unsigned integers would be bigger, confusing and far more complex and probably not worth the trouble. Signed integers are far more useful anyway.

pizzapower wrote:

No. I think it's a pity that hexadecimal numbers can not be converted to non signed value because that would simplify the addresses handling.

That would require a longer integer data type to be done correctly since it is incompatible with how the available data types work.

By gdx

Enlighted (5035)

gdx's picture

15-01-2022, 08:51

Well, I first thought you answer point by point with quotes but I would repeat myself and It would probably be in vain since you seem to come to just contradict to contradict and to get the last say.

By pizzapower

Resident (42)

pizzapower's picture

15-01-2022, 17:00

OK, it's a pity. But there is no easy way around it and because... reasons. If you just want code to get that encoded address, you can use this even shorter version:

10 L1=PEEK(&HF673)
20 L2=PEEK(&HF672)
30 L%=((L1>127)*256+L1)*256+L2
40 PRINT HEX$(L%)
Page 3/3
1 | 2 |