QL floating point to basic conversion routine?

Anything QL Software or Programming Related.
User avatar
NormanDunbar
Forum Moderator
Posts: 2464
Joined: Tue Dec 14, 2010 9:04 am
Location: Buckie, Scotland
Contact:

QL floating point to basic conversion routine?

Post 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!!! :D 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.,


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
tofro
Font of All Knowledge
Posts: 3071
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: QL floating point to basic conversion routine?

Post 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...


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
NormanDunbar
Forum Moderator
Posts: 2464
Joined: Tue Dec 14, 2010 9:04 am
Location: Buckie, Scotland
Contact:

Re: QL floating point to basic conversion routine?

Post by NormanDunbar »

Thanks Tofro. An interesting method, I might look into it and see what happens! :D

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Martin_Head
Aurora
Posts: 967
Joined: Tue Dec 17, 2013 1:17 pm

Re: QL floating point to basic conversion routine?

Post 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$


User avatar
pjw
QL Wafer Drive
Posts: 1608
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL floating point to basic conversion routine?

Post 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.


Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
User avatar
pjw
QL Wafer Drive
Posts: 1608
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL floating point to basic conversion routine?

Post 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..


Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
User avatar
NormanDunbar
Forum Moderator
Posts: 2464
Joined: Tue Dec 14, 2010 9:04 am
Location: Buckie, Scotland
Contact:

Re: QL floating point to basic conversion routine?

Post 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.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
pjw
QL Wafer Drive
Posts: 1608
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL floating point to basic conversion routine?

Post 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!


Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
User avatar
NormanDunbar
Forum Moderator
Posts: 2464
Joined: Tue Dec 14, 2010 9:04 am
Location: Buckie, Scotland
Contact:

Re: QL floating point to basic conversion routine?

Post 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.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
pjw
QL Wafer Drive
Posts: 1608
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL floating point to basic conversion routine?

Post by pjw »

Hi Norm, Im glad you found it useful.


Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
Post Reply