Page 1 of 2
QL floating point to basic conversion routine?
Posted: Mon Jul 22, 2024 4:58 pm
by NormanDunbar
For a little something I'm working on in SuperBASIC, I need a bit of BASIC code to take the 6 bytes representing a floating point number, and convert them back to the actual number. I know, that sounds silly, but its what I need.
I could use my own PEEK_FLOAT from DJ Toolkit, but I'm trying to do this without external toolkits, hence my need for a SuperBASIC function to do the needful.
I one doesn't exist, I will have to write one myself, but I'm lazy!!!

Something like:
Code: Select all
DEFine PROCedure floatConversion(a$)
LOCal FP, ...
:
REMark a$ consists of the 6 bytes that make up a QL float.
:
FP = ...: REMark Convert a$ to a float number, here, somehow!
RETurn FP
END DEFine floatConversion
Cheers,
Norm.,
Re: QL floating point to basic conversion routine?
Posted: Mon Jul 22, 2024 5:12 pm
by tofro
It would be interesting to see what happens if the name table entry for a string (type $0201) would simply be patched with the type ยง0202 (floating point). It could be the QL just crashes, but also wonderful things could happen... (Actually, the value pointer would point to the right thing for your use, and the only real difference between a string and a float in the name table is the type identifier. The other thing is the value pointer of a string points to its length, so probably would have to be incremented by 2.).
But I'm not at all sure if SuperBASIC is happy with its variable types changing on the fly...
Re: QL floating point to basic conversion routine?
Posted: Mon Jul 22, 2024 5:20 pm
by NormanDunbar
Thanks Tofro. An interesting method, I might look into it and see what happens!
Cheers,
Norm.
Re: QL floating point to basic conversion routine?
Posted: Mon Jul 22, 2024 5:37 pm
by Martin_Head
I've just lifted this from my turbo decompiler. It converts between float and hex.
Code: Select all
18950 DEFine FuNction FLT(str$)
18960 REMark Convert a six byte hex string into a number
18970 LOCal exponent,mantissa
18980 IF str$="000000000000" THEN RETurn 0
18990 exponent=HEX(str$(1 TO 4))
19000 mantissa=HEX(str$(5 TO 12))
19010 RETurn mantissa*(2^(exponent-$81F))
19020 END DEFine FLT
19030 :
19040 :
19050 DEFine FuNction FLT$(n)
19060 REMark Convert a Floating point number into a 12 byte string
19070 REMark by PJW & Steven Pool V0.02 03/12/17
19080 LOCal x,m,s
19090 IF n=0 THEN RETurn FILL$("0",12)
19100 IF n<0 THEN
19110 s=-1:m=-n
19120 ELSE
19130 s=1:m=n
19140 END IF
19150 :
19160 IF m>-$80000000 THEN
19170 FOR x=$81F TO $FFF
19180 m=m/2
19190 IF m<$40000000 THEN EXIT x
19200 END FOR x
19210 m=m+m
19220 ELSE
19230 FOR x=$81F TO 0 STEP -1
19240 IF s=-1 THEN
19250 IF m<=$40000000 THEN
19260 m=m+m
19270 ELSE
19280 EXIT x
19290 END IF
19300 END IF
19310 IF s=+1 THEN
19320 IF m<$40000000 THEN
19330 m=m+m
19340 ELSE
19350 EXIT x
19360 END IF
19370 END IF
19380 END FOR x
19390 END IF
19400 m=s*m
19410 RETurn HEX$(x,16)&HEX$(m,32)
19420 END DEFine FLT$
Re: QL floating point to basic conversion routine?
Posted: Mon Jul 22, 2024 10:37 pm
by pjw
Well, FWIW heres mine:
Code: Select all
100 PRINT FLT(PEEK_W(a), PEEK_L(a + 2))
102
104 DEFine FuNction FLT(x, m)
106 IF m = 0 OR x = 0:RETurn 0
108 RETurn m * 2 ^ (x - $81F)
110 END DEFine FLT
112 :
The example (line 100) assumes the number is in memory somewhere, since you mentioned PEEK_FLOAT.
Any legal float will be ok but rubbish could crash the routine.
Re: QL floating point to basic conversion routine?
Posted: Mon Jul 22, 2024 11:02 pm
by pjw
PS: If your float string was derived from another source then you could use these intermediary routines to convert them:
Code: Select all
10 f$ = FLOAT$(-1.23E-46)
20 PRINT FLT(Int%(f$(1 TO 2)), LongInt(f$(3 TO 6)))
30 :
100 DEFine FuNction Int%(n$)
110 LOCal t
120 t = CODE(n$(1)) * 256 + CODE(n$(2))
130 IF t > 32767: RETurn t - 65536
140 RETurn t
150 END DEFine Int%
160 :
170 DEFine FuNction LongInt(n$)
180 RETurn Int%(n$(1 TO 2)) * 65536 + Int%(n$(3 TO 4))
190 END DEFine LongInt
200 :
210 DEFine FuNction FLT(x, m)
220 IF m = 0 OR x = 0:RETurn 0
230 RETurn m * 2 ^ (x - $81F)
240 END DEFine FLT
250 :
The first three lines are just for example (use your own FLOAT$ equivalent to test)
Rather slow and convoluted but thats BASIC for you..
Re: QL floating point to basic conversion routine?
Posted: Tue Jul 23, 2024 6:43 am
by NormanDunbar
Good morning Per, Steve.
Many thanks for your example code. I shall test them out later, hopefully, and see which one I like best. Much appreciation to you both.
Cheers,
Norm.
Re: QL floating point to basic conversion routine?
Posted: Tue Jul 23, 2024 12:20 pm
by pjw
On closer inspection I realised that the LongInt function only works for positive numbers! Hence this might be more appropriate:
Code: Select all
DEFine FuNction LongInt(n$)
LOCal i%, t
t = 0
FOR i% = 1 TO 4: t = t * 256 + CODE(n$(i%))
IF t = 2 ^ 32: RETurn -1: REMark Rounding "error"?
IF t > $7FFFFFFF: RETurn t - 2 ^ 32
RETurn t
END DEFine LongInt
:
It can easily be converted to SuperBASIC.. If speed were essential Id make 2^32 and $7FFFFFFF (= 2^31 - 1) into constants and keep them out of the function and any loops.
Im no mathematician, so if anyone can do better - or find fault with these routines - please let us know!
Re: QL floating point to basic conversion routine?
Posted: Tue Jul 30, 2024 3:10 pm
by NormanDunbar
Afternoon Gents.
I have decided that, as my data are in memory, Per's routine is the best one for me to use.
Thanks both, for your input.
Cheers,
Norm.
Re: QL floating point to basic conversion routine?
Posted: Wed Jul 31, 2024 11:46 am
by pjw
Hi Norm, Im glad you found it useful.