Page 2 of 2
Re: Floating point conversion
Posted: Thu Nov 30, 2017 1:10 pm
by pjw
Yes, Steve, I think you cracked it
So in all its glory, here goes V0.01:
Code: Select all
10 ovf = 2 ^ 30
11 ov2 = 2 ^ 31
12 :
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 > ov2 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 IF m < ovf: m = m + m: ELSE : EXIT x
280 END FOR x
290 END IF
300 m = s * m
310 RETurn HEX$(x, 16) & HEX$(m, 32)
320 END DEFine FLT$
330 :
Re: Floating point conversion
Posted: Thu Nov 30, 2017 3:57 pm
by stevepoole
Hi Per,
Just been testing your latest version which seems to be dead accurate....
The first loop can also be written as :
for x = $81F to $FFF : if m < ov2 : exit x : else m = m / 2
This allows two lines to be deleted, but is it faster ?
Thanks for your code !
Best wishes,
Steve.
Re: Floating point conversion
Posted: Thu Nov 30, 2017 5:54 pm
by pjw
stevepoole wrote:<>
The first loop can also be written as :
for x = $81F to $FFF : if m < ov2 : exit x : else m = m / 2
This allows two lines to be deleted, but is it faster ?
Hi Steve, theres probably not much in it, but a nice tweak all the same
I got the general idea for the algorithm from doing the same in assembler (years ago when I still had some idea of what I was doing). The BASIC version was developed heuristically, without much engagement of the prefrontal cortex!
Ive been trying to shave off the last roxr.l ('cause that what it is), ie line 240 in the V0.01 code above, but havent found a way to do it yet. But perhaps tweaking this more is futile. What is needed is a different approach altogether. A certain person - he with "a brain the size of a planet", would probably reduce the whole thing to three lines of code (viz our foray into FIZZBUZZ some years back. Remember?
)
Re: Floating point conversion
Posted: Sat Dec 02, 2017 5:27 am
by stevepoole
Hi Per,
After still more testing, I note that the series -1, -2, -4, -8, -16 etc gives false results.
I have tweaked a bit, but still cannot locate the cause of the bug.
Perhaps you can ?
Regards,
Steve.
Re: Floating point conversion
Posted: Sat Dec 02, 2017 7:32 am
by stevepoole
Hi again,
For correct powers of two, change the second loop :
for x=$81F to 0 step -1
if s=-1: if m<=ovf: m=m+m: else exit x
if s=+1: if m< ovf: m=m+m: else exit x
end for x
Tested for -1e-615, -1e615, -pi, pi, 1e615, 1e-615
That is a huge range to check in very small STEPs.
But seems OK for the moment.
Will keep running tests, as one tweak may upset other values...
Regards,
Steve.
Re: Floating point conversion
Posted: Mon Dec 04, 2017 1:26 pm
by pjw
Theres been quite some activity behind the scenes here, and this is what weve come up with: (All previous versions are abominations and embarrassments and should be withdrawn from active service immediately and taken behind the woodshed and shot!):
Code: Select all
100 REMark ======================================================
110 REMark Float to Hex by pjw & steven pool
120 REMark V0.02, December 3rd 2017
130 :
140 DEFine FuNction FLTp$(n)
150 LOCal x, m, s
160 IF n = 0: RETurn FILL$('0', 12)
170 IF n < 0: s = -1: m = -n: ELSE : s = 1: m = n
180 IF m > -$80000000 THEN
190 FOR x = $81F TO $FFF
200 m= m / 2
210 IF m < $40000000: EXIT x
220 END FOR x
230 m = m + m
240 ELSE
250 FOR x = $81F TO 0 STEP -1
260 IF s = -1: IF m <= $40000000: m = m + m: ELSE EXIT x
270 IF s = +1: IF m < $40000000: m = m + m: ELSE EXIT x
280 END FOR x
290 END IF
300 m = s * m
310 :
320 RETurn HEX$(x, 16) & HEX$(m, 32)
330 END DEFine FLTp$
340 :
The above shows something of whats going on, hence the inline hex. Howver, Qlib wont even discuss it,
so the below may be more suitable:
Code: Select all
10 ovf = 2^30: ov2 = 2^31: REMark Overflow limits
11 :
500 REMark ======================================================
510 REMark Float to Hex by Steve Pool & pjw
520 :
530 DEFine FuNction FLTs$(n)
540 LOCal x,m,s, x$(4), m$(8)
550 IF n=0: RETurn FILL$('0',12)
560 IF n<0: s=-1: m=-n
570 IF n>0: s=1 : m=n
580 IF m>ov2 THEN
590 FOR x=2079 TO 4095: m=m/2: IF m<ovf: EXIT x: END IF
600 m=m+m
610 ELSE FOR x=2079 TO 0 STEP -1
620 IF s=-1: IF m<=ovf: m=m+m: ELSE EXIT x: END IF
630 IF s=+1: IF m< ovf: m=m+m: ELSE EXIT x: END IF
640 END FOR x
650 END IF : m=s*m: x$=HEX$(x,16): m$=HEX$(m,32) : RETurn x$&m$
660 END DEFine
670 :
They both give correct answers for the whole range of floats (as far as weve been able to ascertain). However, whichever version you use: They are sadly slow when it comes to higher numbers, such as 9E615, as a lot of iterations have to be got through to normalise the numbers.
Strangely, although Qlib will compile it, it doesnt seem to work for numbers > 2^30 under Qlib! Dont yet know why (and Im not sure I care enough to find out!)
Finally, I wrote a single keyword toolkit in assembler. That works in about linear time (as the number it works with is already normalised). 104 bytes of code. Works across the range. If someone really needs this, and cant be bothered to write their own, they know where to get it!
Re: Floating point conversion
Posted: Thu Dec 07, 2017 6:16 am
by stevepoole
Hi Martin,
Yes, I can confirm what Per has posted. The programs have been beta-tested and are bug-free now.
Tested Ok over the full floating-point range of -,+ 9E -,+ 615
And, they Turbo_Compile OK on my system, a QPC2 laptop.
Many thanks to Per for converting his _rext code into Basic for us all...
Regards,
Steve.
Re: Floating point conversion
Posted: Thu Dec 07, 2017 9:56 am
by Martin_Head
Thanks Per and Steve for all the time and effort you have put in.
Martin