BBC BASIC for Windows
« Converting a 40-bit to a 64-bit float? »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 10:30pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Converting a 40-bit to a 64-bit float?  (Read 181 times)
David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
--
User IP Logged

rtr
Guest
xx 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 » User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
--
« Last Edit: Aug 14th, 2014, 10:32am by David Williams » User IP Logged

rtr
Guest
xx 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.
User IP Logged

rtr
Guest
xx 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.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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
 

User IP Logged

rtr
Guest
xx 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.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls