Page 1 of 2

Floating point conversion

Posted: Wed Nov 29, 2017 11:17 am
by Martin_Head
Has anyone got a SuperBASIC routine that will convert a number into the six byte QL Floating Point internal form? Preferably returning a string of 12 Hex digits.

I would like to write a Function to do something like x$=FP$(16453)

Re: Floating point conversion

Posted: Wed Nov 29, 2017 12:04 pm
by tofro
Something along the lines of (Untested, no QL at hand...)

Code: Select all

x = respr (10)
a = a$ : REMark convert from String to float
POKE_F x, a
FOR i = 1 TO 6
   x$ = x$ & HEX$(PEEK (x + i - 1), 8)
END FOR i
PRINT X$
  
(i.e. POKE_F and PEEK combined) should work. POKE_F is part of Turbo Toolkit.

Tobias

Re: Floating point conversion

Posted: Wed Nov 29, 2017 12:28 pm
by JonS
FLOAT$(<number>)

This function takes a floating point number and returns the
internal math representation of the number as a six character
string.
...in PDTK on Dilwyn's site

Re: Floating point conversion

Posted: Wed Nov 29, 2017 1:38 pm
by pjw
Martin_Head wrote:Has anyone got a SuperBASIC routine that will convert a number into the six byte QL Floating Point internal form? Preferably returning a string of 12 Hex digits.

I would like to write a Function to do something like x$=FP$(16453)
If I understood your question correctly, you are looking for something like this?

Code: Select all

100 CLS
110 ovf = 2 ^ 31:    REMark Sign switch
120 ofs = $81F:      REMark Offset/bias
130 :
140 REMark Test
150 PRINT FLT$(20000)
160 PRINT FLT$(-20000)
170 PRINT FLT$(2E6)
180 PRINT FLT$(-2E6)
190 PRINT FLT$(2E-6)
200 PRINT FLT$(-2E-6)
210 PRINT FLT$(222.22)
220 PRINT FLT$(-222.22)
230 :
240 DEFine FuNction FLT$(n)
250 LOCal x, m, s
260 PRINT n,:                   rem ### debug
270 IF n = 0: RETurn FILL$('0', 12)
280 IF n < 0 THEN
290  s = -1: m = -n
300 ELSE
310  s = 1: m = n
320 END IF
330 :
340 FOR x = ofs TO 0 STEP -1
350  m = m + m
360  IF m >= ovf: EXIT x
370 END FOR x
380 m = m / 2
390 m = s * m
400 PRINT FLT(x, m),:           rem ### debug
410 RETurn HEX$(x, 16) & HEX$(m, 32)
420 END DEFine FLT$
430 :
440 DEFine FuNction FLT(x, b)
450 IF b = 0 OR x = 0: RETurn 0
460 RETurn b * 2 ^ (x - ofs)
470 END DEFine FLT
480 :
Its a bit crude, and Im unsure about edge conditions. Also no error trapping.. If you improve it, or find something better, feed it back!

Re: Floating point conversion

Posted: Wed Nov 29, 2017 4:21 pm
by stevepoole
Hi,

Turbo has a FLOAT$ function, ' which returns a six-character string of the specified floating-point number '. See Turbo manual : page 190.

Eg : F$= FLOAT$(PI) : returns 6 ASCII characters ( whose codes are : 8 , 2 , 100 , 135 , 237 , 81 )

Regards,
Steve.

Re: Floating point conversion

Posted: Wed Nov 29, 2017 6:11 pm
by stevepoole
Hi again,

Using Turbo :

100 f$ = FLOAT$(PI) : s$=''
120 for i=1 to 6 : s$=s$ & ( HEX$( CODE( f$(i),8))
130 PRINT s$

Will convert 3.141592654 into 08026487ED51, the HEX value.

Regards,
Steve.

Re: Floating point conversion

Posted: Wed Nov 29, 2017 11:28 pm
by pjw
Actually my routine above only floats "long integers". This one "floats" floats too:

Code: Select all

10 ovf = 2 ^ 30:    REMark pre-Sign switch
20 :
..

100 DEFine FuNction FLT$(n)
110 LOCal x, m, s
120 IF n = 0: RETurn FILL$('0', 12)
130 IF n < 0 THEN
140  s = -1: m = -n
150 ELSE
160  s = 1: m = n
170 END IF
180 :
190 IF m > ovf THEN
200  FOR x = $81F TO $FFF
210   m = m / 2
220   IF m < ovf: EXIT x
230  END FOR x
240  m = m + m
250 ELSE
260  FOR x = $81F TO 0 STEP -1
270   m = m + m
280   IF m > ovf: EXIT x
290  END FOR x
300  m = m / 2
310 END IF
320 m = s * m
330 RETurn HEX$(x, 16) & HEX$(m, 32)
340 END DEFine FLT$
350 :
This is just a rough translation from my assembler original. Im sure there is scope for
optimisation! Or perhaps there is a mathematical solution, without the BASIC loops?

Anyway, since its probably not what you wanted, Martin, it doesnt really matter..

Re: Floating point conversion

Posted: Thu Nov 30, 2017 9:39 am
by stevepoole
Hi Per,

Thanks for your latest code, which I just tested :

Line 10 should read ovf = 2^31 to get a correct answer, (compared to the TURBO example for PI).
But then the routine fails for floats larger than 1E9 ...

The function should operate from -1E-616 to 1e615.
I will try to see if I can debug it.

Regards,
Steve.

Re: Floating point conversion

Posted: Thu Nov 30, 2017 10:32 am
by Martin_Head
Thanks everyone for the replies. I don't really want to go to the trouble of installing a toolkit just for this, So I will probably go for Per's solution.

Martin

Re: Floating point conversion

Posted: Thu Nov 30, 2017 11:29 am
by stevepoole
Hi again,

Per's solution needs several tweaks to get all the right answers , (Tested against the TURBo codes I gave).

Line 10 ovf=2^30 is now OK, but :
read 190 If m> (2^31) THEN
delete 270 and 300
read 280 if m>=ovf: exit x: else m=m+m

This now works in the full range of -1E-615 to 1E615 !
If you find any further bugs, please let us all know...

Regards,
Steve.