Author |
Topic: Converting a 40-bit to a 64-bit float? (Read 180 times) |
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Converting a 40-bit to a 64-bit float?
« Thread started on: Aug 13th, 2014, 9:12pm » |
|
Anyone got any code lying around to do this? Convert a normal, variant 40-bit BB4W float to a 64-bit double precision float. I knew that SORTLIB.BBC includes code for sorting 40-bit floats (and perhaps the answer may lie there), but I didn't really understand the code!
I do intend to convert any solution that might be given to C, because I need it for a function I'm writing (one that accepts co-ordinates in a number of formats: integer, 16:16 fixed-point integer, 40-bit float, 64-bit double).
Thanks.
David. --
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: Converting a 40-bit to a 64-bit float?
« Reply #1 on: Aug 14th, 2014, 09:01am » |
|
on Aug 13th, 2014, 9:12pm, David Williams wrote:Anyone got any code lying around to do this? Convert a normal, variant 40-bit BB4W float to a 64-bit double precision float. |
|
The first thing to say is that in BB4W v6 (which is all I ever use now) variants are 80-bits rather than 40-bits, so if you want your code to work on all current and future versions of BB4W you ought to make allowances for that possibility.
If your code is activated by CALL then the type information is provided in the parameter table (type=5 for 40-bit variant and 10 for 80-bit variant; I ought to update the docs to cover the new data types). If however your code is activated by SYS and you simply pass a pointer, you won't straightforwardly know which it is.
Anyway to answer your question this code converts a 40-bit float in cl:edx into a 64-bit float in ecx:edx:
Code: movzx ecx,cl ;zero-extend exponent
add ecx,895 ;adjust exponent
rol edx,1 ;move sign to LSB
shld ecx,edx,21 ;align exponent
shl edx,20 ;align mantissa
btr edx,20 ;get sign to carry
rcr ecx,1 ;insert sign If you need to deal with integer variants as well as floats you will need extra code.
As this would be messy to convert to C, you could most easily incorporate it as inline assembler in your C source code (you can switch GCC to accept 'Intel' syntax).
To avoid this, and especially considering the BB4W v6 complication, I invariably declare variables explicitly as 64-bits (by adding a # suffix) whenever I need to pass them 'by reference' to assembler code or a DLL. Can't you do the same?
Richard.
|
« Last Edit: Aug 14th, 2014, 09:42am by rtr » |
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: Converting a 40-bit to a 64-bit float?
« Reply #2 on: Aug 14th, 2014, 10:30am » |
|
on Aug 14th, 2014, 09:01am, Richard Russell wrote:However to answer your question this code converts a 40-bit float in cl:edx into a 64-bit float in ecx:edx:
Code: movzx ecx,cl ;zero-extend exponent
add ecx,895 ;adjust exponent
rol edx,1 ;move sign to LSB
shld ecx,edx,21 ;align exponent
shl edx,20 ;align mantissa
btr edx,20 ;get sign to carry
rcr ecx,1 ;insert sign |
|
Well, thank you. I am grateful! It's destined for GLIB2 where I hope to inline it within glib2.h. :)
(After conversion to the awkward AT&T asm syntax, that is.)
[Edit: I had a feeling that it would be possible to use the nicer Intel syntax; I'll look into it]
Quote:To avoid this, and especially considering the BB4W v6 complication, I invariably declare variables explicitly as 64-bits (by adding a # suffix) whenever I need to pass them 'by reference' to assembler code or a DLL. Can't you do the same? |
|
I've passed 64-bit floats by reference to assembler routines many times! My problem was I couldn't figure out how to handle 40-bit floats (in assembler).
Being a rather conservative individual, I'll probably continue to use BB4W v5.95a for as long as it's sensible to do so (and probably after it's officially obsolete and unsupported). If it becomes essential to upgrade, then so be it.
Thanks again for the code.
David. --
|
|
|
|
rtr
Guest
|
 |
Re: Converting a 40-bit to a 64-bit float?
« Reply #3 on: Aug 14th, 2014, 11:55am » |
|
on Aug 14th, 2014, 10:30am, David Williams wrote:I had a feeling that it would be possible to use the nicer Intel syntax; I'll look into it |
|
-masm=intel compiler switch.
Quote:My problem was I couldn't figure out how to handle 40-bit floats (in assembler). |
|
I still haven't quite grasped why you have to. SORTLIB, as a general purpose array sorter, has to work with all data types but otherwise why can't you simply specify that your library/DLL works only with 64-bit floats and that anybody who wishes to use it must add the # suffix?
Quote:Being a rather conservative individual, I'll probably continue to use BB4W v5.95a for as long as it's sensible to do so |
|
I'm not concerned about what you personally choose to use, but rather that any libraries or DLLs that you may create for 'general consumption' work with both v5 and v6. That's currently true of every single library - whether supplied with BB4W or from a third party - as far as I'm aware. If you were to release a v5-specific library (I'm sure you won't) I would be most unhappy.
Quote:and probably after it's officially obsolete and unsupported |
|
As you should be aware, I announced that I would not be 'withdrawing' v5 - in the sense that I will keep the v5.95a UPGRADE.EXE available for download from the website - but all future releases will of course be v6.
A major part of the reason is that it's difficult to carve out a niche for BB4W in a crowded market of BASICs, and support for 80-bit floats and 64-bit integers is sufficiently rare (in fact I don't know any other BASIC with long doubles) that they provide important Unique Selling Points.
Richard.
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: Converting a 40-bit to a 64-bit float?
« Reply #4 on: Aug 14th, 2014, 12:53pm » |
|
on Aug 14th, 2014, 11:55am, Richard Russell wrote:why can't you simply specify that your library/DLL works only with 64-bit floats and that anybody who wishes to use it must add the # suffix? |
|
Further, you could adopt the technique of using a BASIC wrapper library in conjunction with a DLL (there are a number of existing examples such as HIMELIB for the HIME DLL, BB4WMAPMLIB for the MAPM DLL etc.).
With that technique the wrapper can take care of conversion to 64-bits (that may be as simple as adding a # suffix to the formal parameters of its procedures and functions) and the DLL needn't worry about dealing with multiple data types.
It can also be advantageous in providing a more 'friendly' PROC/FN interface to your library rather than forcing the users to grapple with the intricacies of the SYS statement, with the attendant advantage of better validity checking (so more likely to raise a trappable BASIC error rather than crashing).
Richard.
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: Converting a 40-bit to a 64-bit float?
« Reply #5 on: Aug 14th, 2014, 2:16pm » |
|
on Aug 14th, 2014, 11:55am, Richard Russell wrote:-masm=intel compiler switch. |
|
I had used that switch in conjunction with the -S switch (for outputting an assembly language listing), but I hadn't realised that it affected the inline assembler. Maybe it was obvious, but I'm learning. :)
Quote:I still haven't quite grasped why you have to. |
|
Mostly personal preference, admittedly. It's for a routine called gPlotPoints (familiar from GFXLIB), where one supplies pointers to a list of X coordinates and to a list of Y coordinates (haven't fully figured out structure array handling and pointers in C yet -- it's early days).
This demo linked-to below shows what gPlotPoints does (it's nothing that you and most others here haven't seen before):
http://www.bb4wgames.com/temp/gplotpointsdemo.zip
Includes two versions - fixed-point (fxp) and 64-bit double (dbl). The source listing (for inspection by the curious) is included below. You can see why your wrapper idea (for converting 40- to 64-bit floats) isn't really suitable in this case as it would be far too slow. As it happens, I'm getting 60 fps for 3000 points on my slow-ish laptop, both for fixed-point and 64-bit double 'mode'. Not bad considering it's BB4W that's updating the coordinates.
David. --
Code:
REM Example of using gPlotPoints to plot multiple points.
REM This uses fixed-point coordinates format.
REM 3000 points at 60 fps on my 1.66GHz 64-bit Intel Celeron
*ESC OFF
MODE 8 : OFF
ON ERROR REPORT : PRINT " at line "; ERL : END
INSTALL @lib$ + "GLIB2"
PROCInitGLIB( @lib$ + "glib2.dll", g{} )
ON ERROR PROCCleanup : PROCerror
ON CLOSE PROCCleanup : QUIT
GetTickCount% = FN`s("GetTickCount")
REM FN`s() is one of GLIB's internal functions,
REM but nevertheless comes in handy for our purposes!
clr% = FNImport("gLerpClr")
plot% = FNImport("gPlotPoints")
nPts% = 3000
DIM x%( nPts%-1 ), y%( nPts%-1 )
DIM dx%( nPts%-1 ), dy%( nPts%-1 )
DIM col%( nPts%-1 )
FOR I% = 0 TO nPts%-1
x%( I% ) = 640*RND(1) * 2^16
y%( I% ) = 512*RND(1) * 2^16
dx%( I% ) = 4*(RND(1)-0.5) * 2^16
dy%( I% ) = 4*(RND(1)-0.5) * 2^16
col%( I% ) = RND(&FFFFFF)
NEXT I%
maxX% = 640 * 2^16
maxY% = 512 * 2^16
fmt% = 2 : REM coordinates format (fixed-point)
REM 0 = integer
REM 1 = <reserved>
REM 2 = 16:16 fixed-point
REM 3 = 40-bit float (not yet supported)
REM 4 = 64-bit float
frames% = 0
*REFRESH OFF
SYS GetTickCount% TO time0%
REPEAT
SYS clr%, g{}, &803020, &203040
SYS plot%, g{}, fmt%, ^x%(0), ^y%(0), ^col%(0), nPts%
FOR I%=0 TO nPts%-1
x%(I%)+=dx%(I%)
y%(I%)+=dy%(I%)
IF x%(I%)<0 OR x%(I%)>=maxX% dx%(I%)*=-1
IF y%(I%)<0 OR y%(I%)>=maxY% dy%(I%)*=-1
NEXT
PROCDisplay(TRUE)
frames% += 1
SYS GetTickCount% TO time1%
IF time1%-time0%>=1000 THEN
SYS GetTickCount% TO time0%
SYS "SetWindowText", @hwnd%, STR$nPts%+" points | " + STR$frames% + " fps"
frames% = 0
ENDIF
UNTIL FALSE
PROCCleanup
END
DEF PROCerror
*REFRESH ON
CLS : ON : REPORT : PRINT " at line "; ERL;
REPEAT UNTIL INKEY(1)=0
ENDPROC
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: Converting a 40-bit to a 64-bit float?
« Reply #6 on: Aug 14th, 2014, 3:49pm » |
|
on Aug 14th, 2014, 2:16pm, David Williams wrote:It's for a routine called gPlotPoints (familiar from GFXLIB), where one supplies pointers to a list of X coordinates and to a list of Y coordinates |
|
So, just specify that the user of the library must declare those arrays/lists either with a % suffix (for the integer version) or a # suffix (for the float version). There is no need to support 40-bit or 80-bit variants, it just adds complication and slows things down (even if the conversion is done in machine code).
I implore you not to release a library which supports only BB4W v5.
Richard.
|
|
Logged
|
|
|
|
|