F64 - Double Floats

Developed or developing a new product in PureBasic? Tell the world about it.
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

F64 - Double Floats

Post by freedimension »

I hacked a small library for Calculating with Double Floats:

http://www.pan-galactic-gargle-blaster.de/F64.zip

This one is for those who won't or can't wait no more for the native 64bit types.
Karbon
PureBasic Expert
PureBasic Expert
Posts: 2010
Joined: Mon Jun 02, 2003 1:42 am
Location: Ashland, KY
Contact:

Post by Karbon »

You're the man. THANK YOU.
-Mitchell
Check out kBilling for all your billing software needs!
http://www.k-billing.com
Code Signing / Authenticode Certificates (Get rid of those Unknown Publisher warnings!)
http://codesigning.ksoftware.net
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Thanks :lol:
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

OK, here's a "small" Update, 20 more Functions and minor Bugfixes included.
Make sure to read the description. The Function Names have changed slightly, one underscore more to type, but what the h..., readability increased by 300%.
The example is now more detailed, too.

Link stays the same: http://www.pan-galactic-gargle-blaster.de/F64.zip


F64 Version 0.7 - another quality product by freedimension
Germany, Octobre 28th. 2003


1. Introduction
----------------
F64 is a library for those of you who can't wait no more for the native Double Floats (64Bit).
This library is not a replacement for the, hopefully coming soon, native double type.
Also it never will be as fast as native types would be, this is because of the additional procedure calls made.

I still wonder why this wasn't done by someone else before.


2. Usage
---------

Defining a new double variable is as easy as

Code: Select all

df.double
Values can be assigned by simply calling the Function F64Val() or F64Float()

Code: Select all

F64_Val(df.double, "25.0")
F64_Float(df.double, 25.0)
All Functions expecting a double as result are writing this result in the first passed double parameter (df1 or df in the descriptions).
Example:

Code: Select all

df1.double
df2.double
F64_Val(df1, "23") ;df1 becomes 23
F64_Val(df2, "19") ;df2   -"-   19
F64_Add(df1, df2)  ;df1 should now be 42 while df2 remains 19

3. Functions
-------------
Functions marked with an asterisk * return a pointer to the result.


;Conversion
Procedure.s F64_Str(df.double [[, p.l]]); Converts df to a string [with p significant digits]. Returns a String.
You can alter the Output by specifying one or two optional parameters.
The first optional parameter specifies the number of digits behind the dot.
The second further specifies the format of the output.
By now there are 3 Constants for the last parameter
#F64_Format_Decimal Output as decimal number
#F64_Format_Scientific Output as decimal number in scientific format
#F64_Format_Auto Output as one of the above, shortest wins

Procedure F64_Val(df.double); Converts a string to a double.
Procedure F64_Float(df.double, f.f); Converts a float to a double
Procedure.f F64_toFloat(df.double); Returns the float value of df
Procedure F64_toInt(df.double); Returns the integer value of df
*Procedure F64_PI(df.double); Sets df to the number PI
*Procedure F64_E(df.double); Sets df to the euler number e

;Basic Math
* Procedure F64_Add(df1.double, df2.double); Adds two doubles
* Procedure F64_Sub(df1.double, df2.double); Subtracts df2 from df1
* Procedure F64_Mul(df1.double, df2.double); Multiplies two doubles
* Procedure F64_Div(df1.double, df2.double); Divides df1 by df2
* Procedure F64_Inc(df.double); Increases df by 1
* Procedure F64_Dec(df.double); Decreases df by 1

;Additional Math
* Procedure F64_Mod(df1.double, df2.double); Calculates the Remainder of df1/df2
* Procedure F64_Pow(df1.double, df2.double); Calculates df1 to the power of df2

;Logical
Procedure F64_Cmp(df1.double, df2.double); Compares df1 and df2. Returns 1 if df1>df2, 0 if df1=df2 and -1 if df1<df2.
Procedure F64_Equ(df1.double, df2.double); Compares df1 and df2. Returns 1 if df1=df2 else 0.
Procedure F64_Copy(df1.double, df2.double); Copys the value from df2 into the variable df1

;Trigonometry
* Procedure F64_Sin(df.double); Calculates the Sine of df
* Procedure F64_Cos(df.double); Calculates the Cosine of df
* Procedure F64_Tan(df.double); Calculates the Tangent of df
* Procedure F64_ASin(df.double); Calculates the Arcus Sine of df
* Procedure F64_ACos(df.double); Calculates the Arcus Cosine of df
* Procedure F64_ATan(df.double); Calculates the Arcus Tangent of df
* Procedure F64_SinH(df.double); Calculates the Hyperbolic Sine of df
* Procedure F64_CosH(df.double); Calculates the Hyperbolic Cosine of df
* Procedure F64_TanH(df.double); Calculates the Hyperbolic Tangent of df
* Procedure F64_ASinH(df.double); Calculates the Arcus Hyperbolic Sine of df
* Procedure F64_ACosH(df.double); Calculates the Arcus Hyperbolic Cosine of df
* Procedure F64_ATanH(df.double); Calculates the Arcus Hyperbolic Tangent of df
* Procedure F64_Cot(df.double); calculates the cotangent of df
* Procedure F64_CotH(df.double); calculates the hyperbolic cotangent of df
* Procedure F64_ACotH(df.double); calculates the arcus hyperbolic cotangent of df

;Misc
Procedure F64Version(); Returns the Version of this Library, HighWord = Major, LowWord = Minor (no leading 0)


4. Example
-----------
An example can be found in $PB-Root$\Examples\UserLibraries\


5. Known issues
----------------
- By now there are no debugger checks, so be sure to pass only valid Parameters (i.e. no NULLs or other invalid pointers)
- F64Str() : Trailing 0 (zeros) aren't removed, I'll have a look at it in Version 1.0 (that's what I call a Fredism ;-)

That's all for now, but there's no doubt there will soon be more.


6. ToDo
--------
Any ideas?


7. History
-----------
v0.7
- Added F64_Inc, -Dec (slightly Faster (~10-20%) than using F64_Add or F64_Sub)
- Now nested Function Calls are possible. All calculational Functions return the Pointer to the Result.

v0.6
- !!! Inserted underscores _ for better readability (F64_Command instead of F64Command) !!!
- Added F64_ASin, -ACos, -ATan, -SinH, -CosH, -TanH, -ASinH, -ACosH, -ATanH
- Added F64_Cot, -CotH, -ACotH
- Added F64_Equ, -Swap
- Added F64_toInt
- Added F64_E, -PI
- Fixed F64_toFloat
- F64_Str has now 1 parameter (double input) + 2 optional parameters (precision and output format)
- made a resident file with the double structure and 3 Constants (#F64_Format_Decimal, #F64_Format_Scientific and #F64_Format_Auto)

v0.5
- First public Version, so no changes


8. License
-----------
This library is for free, so spread it but please keep the readme.txt attached unaltered.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

thanks freedimension.
very fast routines :D
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

jack wrote:thanks freedimension.
very fast routines :D
:oops: Now, actually they are just wrappers of C code and it was not so hard to code, I was just due to try my rusted C Knowledge once again. Thanks anyway.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

wish list:
sqrt, ln, log10, exp , inverse log10 and chs (change sign) :)
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

jack wrote:wish list:
sqrt, ln, log10, exp , inverse log10 and chs (change sign) :)
sqrt, exp: I thought in a quick'n'dirty lib, pow(xxx, 0.5) or pow(E, yyy)should suffice but your wish is my command, but not too soon.
ln, log: heck, that should be in the library. Try F64_LN and F64_Log, I think I've forgotten to mention them in the description.
inverse log10: what do you mean by this? Something like 1/log10 xxx?
chs: OK, I will look to it
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

thanks freedimension, about inverse log10, i mean 10^x, but your right
pow(10,x) is sufficient :)
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

Download the newest version, 0.9.

It has some new features, including Negate, Sqrt, Exp and Abs
Also I have made a small change to the handling of the functions. Old code stays valid but every calculational function has now an optional parameter for the result value. The original values won't be overwritten if the optional parameter is given.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

only one thing missing, an integer to double function :mrgreen:

thanks freedimension :D
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

there is a bug in the F64 lib, F64_Negate is defined as 1-x instead of 0-x. :(
anyway, i took the liberty to add several missing functions.

Code: Select all

;F64_Chs(x.double,y.double)        ;y = -x    (to replace F64_Negate).
;F64_Frac(x.double,y.double)       ;put fractional part of x into y
;F64_Integer(x.double,y.double)    ;put integer part of x into y
;F64_Int(y.double,x.l)             ;convert long x to double y
;n.l=F64_IsInt(x.double)           ;n=1 if x is integer, 0 if not.
;n.l=F64_Sign(x.double)    ;n=-1 if x<0, n=0 if x=0, n=1 if x>0, n=2 if fperror.

OpenConsole()

Procedure F64_Frac(*x.double,*y.double) ;y=frac(x)
  MaskedCW.w ;esp+8
  SaveCW.w   ;esp+10
! fstcw [esp+8];MaskedCW
  SaveCW=MaskedCW
  MaskedCW=MaskedCW|%110000000000
! fldcw [esp+8];MaskedCW
! mov edx,[esp] ;*x
! fld qword [edx];*x
! fst st1
! frndint
! fsubp st1,st0
! mov edx,[esp+4] ;*y
! fstp qword [edx];*y
! fldcw [esp+10];SaveCW
EndProcedure

Procedure F64_Integer(*x.double,*y.double) ;y=int(x)
  MaskedCW.w ;esp+8
  SaveCW.w   ;esp+10
! fstcw [esp+8];MaskedCW
  SaveCW=MaskedCW
  MaskedCW=MaskedCW|%110000000000
! fldcw [esp+8];MaskedCW
! mov edx,[esp] ;*x
! fld qword [edx];*x
! frndint
! mov edx,[esp+4] ;*y
! fstp qword [edx]
! fldcw [esp+10];SaveCW
EndProcedure

Procedure F64_Int(*y.double,x.l) ;y=(double)x
! fild dword [esp+4]
! mov edx,[esp]
! fstp qword [edx]
EndProcedure

Procedure.l F64_IsInt(*x.double) ;returns 1 if integer,0 if not.
  y.double
  z.double
  F64_Val(z,"0")
  F64_Frac(*x.double,@y.double)
  ProcedureReturn F64_Equ(y,z)
EndProcedure

Procedure F64_Sign(*x.double)   ;returns -1 if x<0,  0 if x=0,  1 if x>0
;optimized by Paul Dixon, thanks Paul  :D 
! mov edx,[esp]
! fld qword [edx] 
! ftst 
! fstsw ax 
! mov al,ah 
! shr al,6      
! xor ah,1  
! xor ah,al 
! shl ah,1 
! Or al,ah 
! And eax,3 
! dec eax
ProcedureReturn
EndProcedure 

Procedure F64_Chs(*x.double,*y.double);y=-x 
! mov edx,[esp] ;*x 
! fld qword [edx] 
! fchs
! mov edx,[esp+4] ;*y 
! fstp qword [edx] 
EndProcedure 

DefType.double x,y,z,v,w
DefType.l n,m,k,l

F64_PI(x)
m=1234567
F64_Frac(x,y)
F64_Integer(x,z)
F64_Chs(x,v)
F64_Int(w,m)
n=F64_Sign(v)
k=F64_IsInt(x)
l=F64_IsInt(w)
PrintN("F64_PI(x)        ;x --> "+F64_Str(x, 15,#F64_Format_Auto))
PrintN("F64_Frac(x,y)    ;y --> "+F64_Str(y, 15,#F64_Format_Auto))
PrintN("F64_Integer(x,z) ;z --> "+F64_Str(z, 15,#F64_Format_Auto))
PrintN("F64_F64_Chs(x,v) ;v --> "+F64_Str(v, 15,#F64_Format_Auto))
PrintN("n=F64_Sign(v)    ;n --> "+Str(n)+"       (v < 0)")
PrintN("m=1234567        ;m --> "+Str(m))
Print("F64_Int(w,m)     ;w --> "+F64_Str(w, 15,#F64_Format_Auto))
PrintN("  the double var w = 1234567")
PrintN("k=F64_IsInt(x)   ;k --> "+Str(k)+"       (no)")
PrintN("l=F64_IsInt(w)   ;l --> "+Str(l)+"       (yes)")
PrintN("")
Print("press return key to end ")
Input()
CloseConsole()

TronDoc
Enthusiast
Enthusiast
Posts: 310
Joined: Wed Apr 30, 2003 3:50 am
Location: 3DoorsDown

Post by TronDoc »

link broken: 400 bad request :( --jb
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

yes, that's an old link and it's broken, you can get it at PureArea.net.
http://www.purearea.net/pb/english/index.htm :)
Post Reply