Jump to content

New Math functions


trancexx
 Share

Recommended Posts

New functiones are _Cosh(), _Sinh(), _Tanh() and "improved" one is _ATan2().

I actually followed UDF standards this time.

Updated post, 23rd October 2008

- functions covered: _ATan2(), _Cosh(), _Frexp(), _Hypot(), _Ldexp(), _Logb(), _Sinh(), _Tanh()

- two versions posted. One using msvcrt.dll and the other using autoits bilt-in functions and operators.

Using msvcrt.dll:

; #FUNCTION# ;===============================================================================
;
; Name...........: _ATan2
; Description ...: Returns the standard position angle (in radians) to the point ($nX, $nY)
; Syntax.........: _ATan2(Const $nY, Const $nX )
; Parameters ....: $nY = y co-ordinate of the point to check
;                  $nX = x co-ordinate of the point to check
; Return values .: Success - Returns the angle, between 0 and 2 pi.
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nY or $nX is not a number (or both).
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......:
; Link ..........;
; Example .......; MsgBox(4096, "_ATan2() Test", "_ATan2( 3, 4 ) = " & _ATan2( 3, 4 ))
;
;==========================================================================================
Func _ATan2(Const $nY, Const $nX)

    If Not (IsNumber($nY) And IsNumber($nX)) Then 
        Return SetError(1, 0, 0)
    EndIf
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_ATan2


; #FUNCTION# ;===============================================================================
;
; Name...........: _Cosh
; Description ...: Returns the hyperbolic cosine of a number
; Syntax.........: _Cosh(Const $nX)
; Parameters ....: $nX = number to calculate its hyperbolic cosine
; Return values .: Success - number
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......: _Tanh, _Sinh
; Link ..........;
; Example .......; MsgBox(4096, "_Cosh() Test", "_Cosh(7) = " & _Cosh(7))
;
;==========================================================================================
Func _Cosh(Const $nX)

    If Not IsNumber($nX) Then 
        Return SetError(1)
    EndIf   
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "cosh", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Cosh


; #FUNCTION# ;===============================================================================
;
; Name...........: _Frexp
; Description ...: Returns the array containing floating-point number together with mantissa and exponent of it
; Syntax.........: _Frexp(Const $nX)
; Parameters ....: $nX = number to calculate its mantissa and exponent
; Return values .: Success - Array which first element $array[0] equals $nX,
;                                        second element $array[1] equals mantissa,
;                                        third element $array[2] equals exponent.
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
;                  Absolute value of mantissa is always greater than or equal to 0.5 and less than 1.0
;                  For every x element of the set of all real numbers it can be written:
;                  x = m*2^n where m equals mantissa and n equals exponent (element of the set of all integers).
; Related .......:
; Link ..........;
; Example .......;
;
;==========================================================================================
Func _Frexp(Const $nX)

    If Not IsNumber($nX) Then 
        Return SetError(1, 0, 0)
    EndIf
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "frexp", "double", $nX, "int*", 1)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    
    Local $a_Array[3] = [$aResult[1], $aResult[0], $aResult[2]]
    
    Return SetError(0, 0, $a_Array)

EndFunc   ;==>_Frexp


; #FUNCTION# ;===============================================================================
;
; Name...........: _Hypot
; Description ...: Returns the hypotenuse of right-angled triangle with cathetus $nA and $nB
; Syntax.........: _Hypot(Const $nA, Const $nB )
; Parameters ....: $nA = catheti
;                  $nB = catheti
; Return values .: Success - Returns number representing hypotenuse
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nA or $nB is not a number (or both).
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......:
; Link ..........;
; Example .......; MsgBox(4096, "_Hypot() Test", "_Hypot( 3, 4 ) = " & _Hypot( 3, 4 ))
;
;==========================================================================================
Func _Hypot(Const $nA, Const $nB)

    If Not (IsNumber($nA) And IsNumber($nB)) Then 
        Return SetError(1, 0, 0)
    EndIf
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "_hypot", "double", $nA, "double", $nB)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Hypot


; #FUNCTION# ;===============================================================================
;
; Name...........: _Ldexp
; Description ...: Returns number calculated from mantissa and exponent
; Syntax.........: _Ldexp(Const $nM, Const $nE )
; Parameters ....: $nM = mantissa
;                  $nE = integer representing exponent
; Return values .: Success - Returns calculated number
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
;                  For every x and m elements of the set of all real numbers it can be written:
;                  x = m*2^n where m equals mantissa and n equals exponent (element of the set of all integers).
; Related .......:
; Link ..........;
; Example .......;
;
;==========================================================================================
Func _Ldexp(Const $nM, Const $nE)

    If Not (IsNumber($nM) And IsInt($nE)) Then 
        Return SetError(1, 0, 0)
    EndIf
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "ldexp", "double", $nM, "int", $nE) ; ldexp is similar to _scalb
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Ldexp


; #FUNCTION# ;===============================================================================
;
; Name...........: _Logb
; Description ...: Extracts exponential value of double-precision floating-point argument.
; Syntax.........: _Logb(Const $nX)
; Parameters ....: $nX = number (d-p f-p arg)
; Return values .: Success - integer representing exponential value
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
;                  For every x element of the set of all real numbers:
;                                                               2^n <= x > 2^n+1 this function returns n (integer)
; Related .......:
; Link ..........;
; Example .......;
;
;==========================================================================================
Func _Logb(Const $nX)

    If Not IsNumber($nX) Then 
        Return SetError(1, 0, 0)
    EndIf   
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "_logb", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Logb


; #FUNCTION# ;===============================================================================
;
; Name...........: _Sinh
; Description ...: Returns the hyperbolic sine of a number
; Syntax.........: _Sinh(Const $nX)
; Parameters ....: $nX = number to calculate its hyperbolic sine
; Return values .: Success - number
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......: _Tanh, _Cosh
; Link ..........;
; Example .......; MsgBox(4096, "_Sinh() Test", "_Sinh(7) = " & _Sinh(7))
;
;==========================================================================================
Func _Sinh(Const $nX)

    If Not IsNumber($nX) Then 
        Return SetError(1, 0, 0)
    EndIf
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "sinh", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Sinh


; #FUNCTION# ;===============================================================================
;
; Name...........: _Tanh
; Description ...: Returns the hyperbolic tangent of a number
; Syntax.........: _Tanh(Const $nX)
; Parameters ....: $nX = number to calculate its hyperbolic tangent
; Return values .: Success - number
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......: _Sinh, _Cosh
; Link ..........;
; Example .......; MsgBox(4096, "_Tanh() Test", "_Tanh(7) = " & _Tanh(7))
;
;==========================================================================================
Func _Tanh(Const $nX)

    If Not IsNumber($nX) Then 
        Return SetError(1, 0, 0)
    EndIf   
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "tanh", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Tanh

I would recommend using latter.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Yay maths! You can never have enough maths UDFs.

Just one point, should you be closing the DLL after opening it, or does it not matter?

Good stuff.

- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!
Link to comment
Share on other sites

For UDF standards there's a few things...

Func _ATan2(Const $nY, Const $nX)

    If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, "err")
   
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
    If Not @error Then
        DllClose($h_DLL)
        Return SetError(0, 0, $aResult[0])
    EndIf
   
    DllClose($h_DLL)
    Return SetError(2, 0, "err")

EndFunc  ;==>_ATan2

SetError(1, 0, "err")

If an error occurs it should be an empty string, or a 0 value? Since were dealing with numbers, right?

For Atan2() in Math.au3 it is returning 0 and setting @Error accordingly.

SetError(1)
Return 0

Also you could very well reduce the code size, as you'll have to use DllClose() no matter what..

If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
DllClose($h_DLL)

If Not @Errror Then

One of my biggest pet peeves is this bit of code. You should exit as soon as an error occurs.

If @error Then Return SetError(2, 0, 0)

Here's the modified _Atan2 for example...

Func _ATan2(Const $nY, Const $nX)

    If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, 0)
   
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
    DllClose($h_DLL)
    
    If @error Then Return SetError(2, 0, 0)
    
    Return $aResult[0]
EndFunc  ;==>_ATan2
Edited by mrRevoked
Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

Since we're just opening and closing the DLL, which seems unnecessary at this point, we could just remove those bits and use this..

Func _ATan2(Const $nY, Const $nX)
    If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, 0)
    Local $aResult = DllCall("msvcrt.dll", "double:cdecl", "atan2", "double", $nY, "double", $nX)
    If @error Then Return SetError(2, 0, 0)
    Return $aResult[0]
EndFunc   ;==>_ATan2

Thanks for sharing.

Edited by mrRevoked
Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

@mrRevoked; thank you for your effort to make this more advanced, I appreciate that. It's a great opportunity to learn.

I have few remarks to your post(s). Will update this one with them. Please stick arround.

edit:

Since we're just opening and closing the DLL, which seems unnecessary at this point, we could just remove those bits and use this..

Func _ATan2(Const $nY, Const $nX)
    If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, 0)
    Local $aResult = DllCall("msvcrt.dll", "double:cdecl", "atan2", "double", $nY, "double", $nX)
    If @error Then Return SetError(2, 0, 0)
    Return $aResult[0]
EndFunc   ;==>_ATan2
I had this approach here and it turned to be a flaw. So I would discourage anyone of doing it that way. It may work, and again, it may not. Btw, I got msvfw32.dll to work (link).

SetError(1, 0, "err")

If an error occurs it should be an empty string, or a 0 value? Since were dealing with numbers, right?

For Atan2() in Math.au3 it is returning 0 and setting @Error accordingly.

SetError(1)
Return 0
I took this under consideration. This was my conclusions:

- returning 0 is wrong, it could inicate the result if someone is lazy not to check the error (often case)

- returning empty string is more appropriate

- if it can be empty one than it can very well be not empty one ("err" looked just fine)

Also you could very well reduce the code size, as you'll have to use DllClose() no matter what..

If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
DllClose($h_DLL)

If Not @Errror Then

One of my biggest pet peeves is this bit of code. You should exit as soon as an error occurs.

If @error Then Return SetError(2, 0, 0)

Here's the modified _Atan2 for example...

Func _ATan2(Const $nY, Const $nX)

    If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, 0)
   
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
    DllClose($h_DLL)
    
    If @error Then Return SetError(2, 0, 0)
    
    Return $aResult[0]
EndFunc;==>_ATan2
I try to be very thorough. I had this as a option but dropped it because that error checking is not checking the thing that needs to be checked. Calling DllClose() will set @error to 0 if error rised after making DllCall(). Right?

For example, if for some reason function atan2 is no longer called as it is now (in new versions of this dll by microsoft) than DllCall() will make an error and there will be no $aResult[0] to return thus causing failure of this function (and very likely everything else). We will not be aware of the error prior eventual crash because @error will be set to 0 with DllClose().

As always there is a workaround. Maybe like this:

Func _ATan2(Const $nY, Const $nX)

    If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, "err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "err")
    EndIf
        
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])
    
EndFunc ;==>_ATan2

Please comment.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

- returning 0 is wrong, it could inicate the result if someone is lazy not to check the error (often case)

- returning empty string is more appropriate

I agree with this....what if the true math result WAS zero, then it looks like an error where there wasn't one.

What about something like this:

Func _ATan2($nX,$nY,$h_DLL = "msvcrt.dll")

    If Not IsNumber($nY) Or Not IsNumber($nX) Or $h_DLL = -1 Then
        SetError(1,0)
        Return ""
    EndIf
   
    Local $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)

    If @error Then 
        SetError(1,@error)
        Return ""
    EndIf
    
    Return $aResult[0]
    
EndFunc

This then gives the user the option to open and close the DLL themselves if needed, and it returns the DLL error in @extended if there is one.

- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!
Link to comment
Share on other sites

@trancexx

Calling DllClose() will set @error to 0 if error rised after making DllCall(). Right?

I didn't see anywhere in the documentation that "DllClose" would set @Error to 0 if at all, but it looks like your right.

$hDLL = DllOpen("msvcrt.dll")
DllCall($hDLL, "double:cdecl", "atan2", "double", 0, "double", 0)
SetError(1)
ConsoleWrite("before: "& @error &@lf);returns 1
DllClose($hDLL)
ConsoleWrite("after: "& @error &@lf);returns 0

- returning 0 is wrong, it could inicate the result if someone is lazy not to check the error (often case)

- returning empty string is more appropriate

The UDF's and Internal functions are hardly consistent with setting @Error appropriately, so again this is true, I think the return value should be empty when an error occurs.

In this case andybiochem's method would be the best approach?

Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

What you're saying is basically this:

int Add(int a, int b)
{
   return String.Empty();
}

Now you tell me how that makes sense.

It doesn't. There's no error checking in your example. the return value should be empty when an error occurs You're misunderstanding what I said. :P
Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

What you're saying is basically this:

int Add(int a, int b)
{
   return String.Empty();
}

Now you tell me how that makes sense.

??? I don't think that has been said.

What HAS been said is, "if there is an error, better to return an empty string than zero"

...which I agree with for maths functions where zero is a viable return value.

[EDIT] Although, that said, "" is treated in the same way as zero :P

$a = 10
$b = ""
MsgBox(0,"",$a * $B)

...returns zero.

Edited by andybiochem
- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!
Link to comment
Share on other sites

I was emphasizing what trancexx has said.

I took this under consideration. This was my conclusions:

- returning 0 is wrong, it could inicate the result if someone is lazy not to check the error (often case)

- returning empty string is more appropriate

- if it can be empty one than it can very well be not empty one ("err" looked just fine)

Here's an example

Int

Returns the integer (whole number) representation of an expression.

Success: Returns a integer.

Failure: Returns 0 sets @error to 1 if not an integer, float or string.

ConsoleWrite( Int ( 0.3) ) ; returns 0

ConsoleWrite( Int ( "oh hello there") ) ; returns 0

Last time I've checked 0 was an Integer.

Edited by mrRevoked
Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

It doesn't. There's no error checking in your example. the return value should be empty when an error occurs You're misunderstanding what I said. :P

I left out the error checking since no universal way to check for error exists in C# afaik (there's a few methods: exceptions, checking return value etc.). I'll make it more obvious:

double Divide(double a, double b)
{
   if (b == 0) {
      return String.Empty();
   } else {
      return a /b;
   }
}

Explain please.

Edit: I realise this is coming on a bit hard, but I don't intend this as flaming or anything negative. I just want to hear your reason why an empty string is good.

Edited by Manadar
Link to comment
Share on other sites

If an error occurs you shouldn't return "err" but "" (empty string) or 0 (zero).

And btw, here are some more funcs you can wrap :Phttp://archive.notam02.no/arkiv/windows/sn.../include/math.h

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

If an error occurs you shouldn't return "err" but "" (empty string) or 0 (zero).

And btw, here are some more funcs you can wrap :(http://archive.notam02.no/arkiv/windows/sn.../include/math.h

I'm ontop of it. Most of them are builted and the rest will be included here (I hope).

About not "err"... It is quite common to represent indefinite values by strings in math (trigonometry for example) or even errors.

You will get strings out of quite a few (or some :P ) math functions inside msvcrt.dll

But, I will adjust this to what is agreed (when is agreed).

What is your opinion on DllOpen() function in this case?

But, to speak generally.

msvcrt.dll is C++ Runtime Library and I believe that it can be excused from DllOpen() with no fear of consequences. Does this make sense?

Most important thing about math functions is to return precise values and to return fast. Enything that slows them is bad.

When dealing with graphic or whatever speed is crucial, so anything to make it faster. Kingdom for a horse! -said Richard.

I have made few more functions. Will not edit first post but will pos them here. "err" is changed to "-1.#err" for now. As I said I will adjust it to what is agreed.

More functions plus the ones from the first post:

Global $x = 4.7
Global $y = 34.2

ConsoleWrite(_ATan2($x, $y) & @CRLF)

ConsoleWrite(_Cosh($x) & @CRLF)

Global $array = _Frexp($y)
If IsArray($array) Then ConsoleWrite($array[0] & " = " & $array[1] & " * 2^" & $array[2] & @CRLF)

ConsoleWrite(_Hypot($x, $y) & @CRLF)

ConsoleWrite(_Ldexp($x, 12) & @CRLF)

ConsoleWrite(_Logb($y) & @CRLF)

ConsoleWrite(_Sinh($x) & @CRLF)

ConsoleWrite(_Tanh($x) & @CRLF)





; #FUNCTION# ;===============================================================================
;
; Name...........: _ATan2
; Description ...: Returns the standard position angle (in radians) to the point ($nX, $nY)
; Syntax.........: _ATan2(Const $nY, Const $nX )
; Parameters ....: $nY = y co-ordinate of the point to check
;                  $nX = x co-ordinate of the point to check
; Return values .: Success - Returns the angle, between 0 and 2 pi.
;                  Failure - Returns "-1.#err" and Sets @error:
;                  |0 - No error.
;                  |1 - $nY or $nX is not a number (or both).
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......:
; Link ..........;
; Example .......; MsgBox(4096, "_ATan2() Test", "_ATan2( 3, 4 ) = " & _ATan2( 3, 4 ))
;
;==========================================================================================
Func _ATan2(Const $nY, Const $nX)

    If Not IsNumber($nY) Or Not IsNumber($nX) Then Return SetError(1, 0, "-1.#err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "atan2", "double", $nY, "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "-1.#err")
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_ATan2


; #FUNCTION# ;===============================================================================
;
; Name...........: _Cosh
; Description ...: Returns the hyperbolic cosine of a number
; Syntax.........: _Cosh(Const $nX)
; Parameters ....: $nX = number to calculate its hyperbolic cosine
; Return values .: Success - number
;                  Failure - Returns "-1.#err" and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......: _Tanh, _Sinh
; Link ..........;
; Example .......; MsgBox(4096, "_Cosh() Test", "_Cosh(7) = " & _Cosh(7))
;
;==========================================================================================
Func _Cosh(Const $nX)

    If Not IsNumber($nX) Then Return SetError(1, 0, "-1.#err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "cosh", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "-1.#err")
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Cosh


; #FUNCTION# ;===============================================================================
;
; Name...........: _Frexp
; Description ...: Returns the array containing floating-point number together with mantissa and exponent of it
; Syntax.........: _Frexp(Const $nX)
; Parameters ....: $nX = number to calculate its mantissa and exponent
; Return values .: Success - Array which first element $array[0] equals $nX,
;                                        second element $array[1] equals mantissa,
;                                        third element $array[2] equals exponent.
;                  Failure - Returns 0 and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
;                  Absolute value of mantissa is always greater than or equal to 0.5 and less than 1.0
;                  For every x element of the set of all real numbers it can be written:
;                  x = m*2^n where m equals mantissa and n equals exponent (element of the set of all integers).
; Related .......:
; Link ..........;
; Example .......;
;
;==========================================================================================
Func _Frexp(Const $nX)

    If Not IsNumber($nX) Then Return SetError(1, 0, 0)
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "frexp", "double", $nX, "int*", 1)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, 0)
    EndIf
    
    DllClose($h_DLL)
    
    Local $a_Array[3] = [$aResult[1], $aResult[0], $aResult[2]]
    
    Return SetError(0, 0, $a_Array)

EndFunc   ;==>_Frexp


; #FUNCTION# ;===============================================================================
;
; Name...........: _Hypot
; Description ...: Returns the hypotenuse of right-angled triangle with cathetus $nA and $nB
; Syntax.........: _Hypot(Const $nA, Const $nB )
; Parameters ....: $nY = catheti
;                  $nX = catheti
; Return values .: Success - Returns number representing hypotenuse
;                  Failure - Returns "1.#err" and Sets @error:
;                  |0 - No error.
;                  |1 - $nA or $nB is not a number (or both).
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......:
; Link ..........;
; Example .......; MsgBox(4096, "_Hypot() Test", "_Hypot( 3, 4 ) = " & _Hypot( 3, 4 ))
;
;==========================================================================================
Func _Hypot(Const $nA, Const $nB)

    If Not IsNumber($nA) Or Not IsNumber($nB) Then Return SetError(1, 0, "-1.#err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "_hypot", "double", $nA, "double", $nB)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "-1.#err")
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Hypot


; #FUNCTION# ;===============================================================================
;
; Name...........: _Ldexp
; Description ...: Returns number calculated from mantissa and exponent
; Syntax.........: _Ldexp(Const $nM, Const $nE )
; Parameters ....: $nM = mantissa
;                  $nE = integer representing exponent
; Return values .: Success - Returns calculated number
;                  Failure - Returns -1.#err and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
;                  For every x and m elements of the set of all real numbers it can be written:
;                  x = m*2^n where m equals mantissa and n equals exponent (element of the set of all integers).
; Related .......:
; Link ..........;
; Example .......;
;
;==========================================================================================
Func _Ldexp(Const $nM, Const $nE)

    If Not IsNumber($nM) Or Not IsInt($nE) Then Return SetError(1, 0, "-1.#err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "ldexp", "double", $nM, "int", $nE) ; ldexp is similar to _scalb
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "-1.#err")
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Ldexp


; #FUNCTION# ;===============================================================================
;
; Name...........: _Logb
; Description ...: Extracts exponential value of double-precision floating-point argument.
; Syntax.........: _Logb(Const $nX)
; Parameters ....: $nX = number (d-p f-p arg)
; Return values .: Success - integer representing exponential value
;                  Failure - Returns "1.#err" and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
;                  For every x element of the set of all real numbers:
;                                                               2^n <= x > 2^n+1 this function returns n (integer)
; Related .......:
; Link ..........;
; Example .......;
;
;==========================================================================================
Func _Logb(Const $nX)

    If Not IsNumber($nX) Then Return SetError(1, 0, "-1.#err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "_logb", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "-1.#err")
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Logb


; #FUNCTION# ;===============================================================================
;
; Name...........: _Sinh
; Description ...: Returns the hyperbolic sine of a number
; Syntax.........: _Sinh(Const $nX)
; Parameters ....: $nX = number to calculate its hyperbolic sine
; Return values .: Success - number
;                  Failure - Returns "-1.#err" and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......: _Tanh, _Cosh
; Link ..........;
; Example .......; MsgBox(4096, "_Sinh() Test", "_Sinh(7) = " & _Sinh(7))
;
;==========================================================================================
Func _Sinh(Const $nX)

    If Not IsNumber($nX) Then Return SetError(1, 0, "-1.#err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "sinh", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "-1.#err")
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_Sinh


; #FUNCTION# ;===============================================================================
;
; Name...........: _Tanh
; Description ...: Returns the hyperbolic tangent of a number
; Syntax.........: _Tanh(Const $nX)
; Parameters ....: $nX = number to calculate its hyperbolic tangent
; Return values .: Success - number
;                  Failure - Returns "-1.#err" and Sets @error:
;                  |0 - No error.
;                  |1 - $nX is not a number.
;                  |2 - msvcrt.dll related problem
; Author ........: trancexx
; Modified.......:
; Remarks .......: This function uses msvcrt.dll
; Related .......: _Sinh, _Cosh
; Link ..........;
; Example .......; MsgBox(4096, "_Tanh() Test", "_Tanh(7) = " & _Tanh(7))
;
;==========================================================================================
Func _Tanh(Const $nX)

    If Not IsNumber($nX) Then Return SetError(1, 0, "-1.#err")
    
    Local $aResult
    Local $h_DLL = DllOpen("msvcrt.dll")
    If $h_DLL <> -1 Then $aResult = DllCall($h_DLL, "double:cdecl", "tanh", "double", $nX)
    If @error Then
        DllClose($h_DLL)
        Return SetError(2, 0, "-1.#err")
    EndIf
    
    DllClose($h_DLL)
    Return SetError(0, 0, $aResult[0])

EndFunc   ;==>_TanhoÝ÷ Ù©Ýɸ¨r¦ßÛ0k(Z½ëǺ×(ºWbµ·¢w¥G­+»-}ì%w¬¡ùÞ«¨´Æ­«·ªê-jëh×6#include-once
$aModule = DllCall('kernel32.dll', 'ptr', 'GetModuleHandle', 'str', 'msvcrt.dll')
If Not $aModule[0] Then DllOpen("msvcrt.dll")

And then using "DllCall("msvcrt.dll", ..." to avoid DllOpen() every time.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

I was emphasizing what trancexx has said.

Here's an example

Int

Returns the integer (whole number) representation of an expression.

Success: Returns a integer.

Failure: Returns 0 sets @error to 1 if not an integer, float or string.

ConsoleWrite( Int ( 0.3) ) ; returns 0

ConsoleWrite( Int ( "oh hello there") ) ; returns 0

Last time I've checked 0 was an Integer.

If it returns 0 it doesn't mean that it has to be right. This most certanly is not a bug. Not AutoIt's. This is inherited behaviour.

After making a whole circle from start to end Int() is derived out of this (translated to AutoIt):

Func _Int($x)
    
    Local $aResult = DllCall("msvcrt.dll", "double:cdecl", "modf", "double", $x, "double*", 0)

    Return $aResult[2]

EndFunc

I'm questioning this behaviour.

But, what do I know... :P

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

I think at this point we're discussing personal incredulance as to which is the 'best' method to deal with these sort of functions, and the setting of some sort of standard.

I think that is the job of the devs - Jon, Valik, Jos, SmokeN etc.

What sort of return would they want to see? i.e. what is the direction of AutoIt here?

- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!
Link to comment
Share on other sites

I think at this point we're discussing personal incredulance as to which is the 'best' method to deal with these sort of functions, and the setting of some sort of standard. I think that is the job of the devs - Jon, Valik, Jos, SmokeN etc.

I disagree. You should let your personal preferences be heard and the argumentation behind them, so that you may inspire others and let them see this problem from another perspective and possibly come up with other and better solutions. For the sake of open discussion.

Constantly trying to force your opinions onto others is another matter all together and should never be allowed.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...