Leaderboard
Popular Content
Showing content with the highest reputation on 08/31/2015 in all areas
-
I needed this library to continue working on one or two of my projects. Hopefully it will be of use to someone else too. These functions attempt to perform accurate calculations for the largest Int-64 values, testing for integer overflow and resorting to floats when results go out of range. This library is primarily intended to be used with Int-32 or Int-64 values and it offers no advantage whatsoever to pass floats as parameters. It only makes sense if you intend to perform accurate calculations on large Int-64 values. I know this can be done using strings too, but I prefer not to speculate as to the difference in time penalties. ; #INDEX# ====================================================================================================================== ; Title .........: operator64 ; AutoIt Version : 3.3.14.0 ; Language ......: English ; Description ...: Helper functions for basic maths operations to be used with Int-32 and Int-64 numeric data types. ; Notes .........: Tests for integer overflow and attempts to correct for small inaccuracies affecting certain calculations. ; Return values are cast as Int-32 or Int-64 when possible, otherwise the result will be returned as a double. ; If it is not possible to return an Int-64 data type, the @extended flag is always set to non zero. ; Extended return values indicate that 100% accuracy cannot be guaranteed or that the result is ambiguous. ; The following values are valid for all functions in this library ; |@error = 1 The input or first operand is not an integer. ; |@error = 2 The second operand is not an integer. ; |@error = 3 Internal function error (ignore). ; |@extended = 1 The result is limited to double precision. ; |@extended = 2 The result is not an integer. ; |@extended = 3 The result is out of range for Int-64. ; |@extended = 4 The result is infinity. ; |@extended = 5 The result is an imaginary number. ; When an error occurs, the @extended flag is always set to non zero and a value returned regardless. ; Author(s) .....: czardas ; ============================================================================================================================== ; #CURRENT# ==================================================================================================================== ; _Abs64 ; _Add64 ; _Divide64 ; _Multiply64 ; _Power64 ; _Root64 ; _Subtract64 ; ============================================================================================================================== ; #INTERNAL_USE_ONLY#=========================================================================================================== ; __DoubleTo64 ; __Integer64 ; __OverflowDetect ; __Product64 ; __WholeNumberDivision ; ============================================================================================================================== ; #FUNCTION# =================================================================================================================== ; Name...........: _Abs64 ; Description ...: Returns the absolute value of an integer. ; Syntax.........: _Abs64($iInteger) ; Parameters.....; $iInteger - The integer to operate on. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@error = 1 The input parameter is not an integer. ; |@extended = 2 The result is not an integer. ; |@extended = 3 The absolute value (2^63) is out of range for Int-64. ; Author.........: czardas ; ============================================================================================================================== Func _Abs64($iInteger) $iInteger = __Integer64($iInteger) If @error Then Return SetError(1, 2, Abs($iInteger)) If $iInteger = 0x8000000000000000 Then Return SetExtended(3, Abs($iInteger)) Return $iInteger < 0 ? $iInteger *-1 : $iInteger EndFunc ;==> _Abs64 ; #FUNCTION# =================================================================================================================== ; Name...........: _Add64 ; Description ...: Adds two integers together. ; Syntax.........: _Add64($iOperand_1, $iOperand_2) ; Parameters.....; $iOperand_1 - The first operand. ; $iOperand_2 - The second operand. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@error = 1 The first parameter is not an integer. ; |@error = 2 The second parameter is not an integer. ; |@extended = 1 The result is limited to double precision. ; |@extended = 3 The result is out of range for Int-64. ; Author.........: czardas ; ============================================================================================================================== Func _Add64($iOperand_1, $iOperand_2) $iOperand_1 = __Integer64($iOperand_1) If @error Then Return SetError(1, 1, __DoubleTo64($iOperand_1 + $iOperand_2)) ; may still return an integer $iOperand_2 = __Integer64($iOperand_2) If @error Then Return SetError(2, 1, __DoubleTo64($iOperand_1 + $iOperand_2)) ; ditto Local $bOverflow, $nResult $bOverflow = __OverflowDetect('+', $iOperand_1, $iOperand_2, $nResult) Return SetExtended($bOverflow *3, $nResult) EndFunc ;==> _Add64 ; #FUNCTION# =================================================================================================================== ; Name...........: _Divide64 ; Description ...: Divides two integers. ; Syntax.........: _Divide64($iOperand_1, $iOperand_2) ; Parameters.....; $iOperand_1 - The first operand. ; $iOperand_2 - The second operand. ; Failure returns the executed expression and sets the following flags: ; |@error = 1 The first parameter is not an integer. ; |@error = 2 The second parameter is not an integer. ; |@extended = 1 The result is limited to double precision. ; |@extended = 2 The result is not an integer. ; |@extended = 4 The result is infinity. ; Author.........: czardas ; Comments ......; Due to internal rounding, errors may return an integer with the extended flag set to 2. This is not a bug! ; ============================================================================================================================== Func _Divide64($iOperand_1, $iOperand_2) $iOperand_1 = __Integer64($iOperand_1) If @error Then Return SetError(1, 1, __DoubleTo64($iOperand_1 / $iOperand_2)) ; may still return an integer $iOperand_2 = __Integer64($iOperand_2) If @error Then Return SetError(2, 1, __DoubleTo64($iOperand_1 / $iOperand_2)) ; as above If $iOperand_1 = 0x8000000000000000 Then ; this is not dealt with by the internal function If $iOperand_2 = 0x8000000000000000 Then Return 1 ; $iOperand_1 is divided by itself ; divide both values by 2 to remain within the specified range of the function __WholeNumberDivision() $iOperand_1 = 0xC000000000000000 ; -4611686018427387904 $iOperand_2 = __WholeNumberDivision($iOperand_2, 2) If @extended Then Return SetExtended(@extended, $iOperand_1 / $iOperand_2) EndIf Local $nResult = __WholeNumberDivision($iOperand_1, $iOperand_2) Return SetExtended(@extended, $nResult) EndFunc ;==> _Divide64 ; #FUNCTION# =================================================================================================================== ; Name...........: _Multiply64 ; Description ...: Multiplies two integers together. ; Syntax.........: _Multiply64($iOperand_1, $iOperand_2) ; Parameters.....; $iOperand_1 - The first operand. ; $iOperand_2 - The second operand. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@error = 1 The first parameter is not an integer. ; |@error = 2 The second parameter is not an integer. ; |@extended = 2 The result is not an integer. ; |@extended = 3 The result is out of range for Int-64. ; Author.........: czardas ; Comments ......; Due to internal rounding, errors may return an integer with the extended flag set to 2. This is not a bug! ; ============================================================================================================================== Func _Multiply64($iOperand_1, $iOperand_2) $iOperand_1 = __Integer64($iOperand_1) If @error Then Return SetError(1, 2, $iOperand_1 * $iOperand_2) $iOperand_2 = __Integer64($iOperand_2) If @error Then Return SetError(2, 2, $iOperand_1 * $iOperand_2) Local $iProduct = __Product64($iOperand_1, $iOperand_2) Return SetExtended(@extended, $iProduct) EndFunc ;==> _Multiply64 ; #FUNCTION# =================================================================================================================== ; Name...........: _Power64 ; Description ...: Raises an integer to the power of a second integer. ; Syntax.........: _Power64($iInteger, $iPower) ; Parameters.....; $iInteger - The integer to operate on. ; $iPower - The power to raise the integer to. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@error = 1 The first parameter is not an integer. ; |@error = 2 The second parameter is not an integer. ; |@extended = 1 The result is limited to double precision. ; |@extended = 3 The result is out of range for Int-64. ; Author.........: czardas ; ============================================================================================================================== Func _Power64($iInteger, $iPower) $iInteger = __Integer64($iInteger) If @error Then Return SetError(1, 1, $iInteger ^ $iPower) $iPower = __Integer64($iPower) If @error Then Return SetError(2, 1, $iInteger ^ $iPower) If $iInteger = 1 Or $iPower = 0 Then Return 1 If $iPower < 0 Or $iPower > 63 Then Return SetExtended(1, $iInteger ^ $iPower) Local $iTriggers = 0, $iCount = 0, $iPow = $iPower While $iPow > 1 If Mod($iPow, 2) Then $iPow -= 1 Else ; to reduce calls to __Product64() ; triggers indicate the product should be squared (see next loop) $iTriggers += 2 ^ $iCount ; set trigger $iPow /= 2 EndIf $iCount += 1 WEnd Local $iOperand, $iResult = $iInteger For $i = $iCount -1 To 0 Step -1 ; multiply the product either by itself or the original value $iOperand = BitAND($iTriggers, 2^$i) ? $iResult : $iInteger $iResult = __Product64($iResult, $iOperand) If @extended Then Return SetExtended(3, $iInteger ^ $iPower) Next Return $iResult EndFunc ;==> _Power64 ; #FUNCTION# =================================================================================================================== ; Name...........: _Root64 ; Description ...: Calculates the nth root of an integer. ; Syntax.........: _Root64($iInteger, $iRoot) ; Parameters.....; $iInteger - The integer to operate on. ; $iRoot - The root of the integer to calculate. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@error = 1 The first parameter is not an integer. ; |@error = 2 The second parameter is not an integer. ; |@extended = 1 The result is limited to double precision. ; |@extended = 2 The result is not an integer. ; |@extended = 5 The result is an imaginary number. ; Author.........: czardas ; Comments ......; _Root64() has limited application beyond forcing an integer return value whenever possible. ; Roots of negative integers return a defined value if one exists, otherwise the result is always undefined. ; ============================================================================================================================== Func _Root64($iInteger, $iRoot) $iInteger = __Integer64($iInteger) If @error Then Return SetError(1, 1, $iInteger ^ (1 / $iRoot)) $iRoot = __Integer64($iRoot) If @error Then Return SetError(2, 1, $iInteger ^ (1 / $iRoot)) If $iRoot > 63 Or $iRoot < 1 Then Return SetExtended(1, $iInteger ^ (1 / $iRoot)) ; out of range If $iRoot = 1 Then Return $iInteger Local $iSign = $iInteger < 0 ? -1 : 1 If $iSign = -1 And Not Mod($iRoot, 2) Then Return SetExtended(5, $iInteger ^ (1 / $iRoot)) ; undefined If $iInteger = 0x8000000000000000 Then ; here the absolute value cannot be represented by Int-64 ; a small set of defined return values are simply hard coded Local $aMaxRoot = [[3,-2097152],[7,-512],[9,-128],[21,-8],[63,-2]] ; there are only five cases For $i = 0 To 4 If $iRoot = $aMaxRoot[$i][0] Then Return $aMaxRoot[$i][1] Next Return SetExtended(2, $iInteger ^ (1 / $iRoot)) ; the return value is not an integer EndIf ; positive values are used to calculate the odd roots of negative integers Local $iOperand = $iSign = 1 ? $iInteger : $iInteger *-1 ; here the margin of error with Int() is probably too small to necessitate further processing Local $iReturn = Int($iOperand ^ (1 / $iRoot)) ; check the result Local $iCompare = $iReturn For $i = 2 To $iRoot $iCompare *= $iReturn Next ; the chances that this comparison will fail seem negligible - see comments above If $iCompare <> $iOperand Then Return SetExtended(2, $iInteger ^ (1 / $iRoot)) ; the return value is not an integer Return $iReturn * $iSign EndFunc ;==> _Root64 ; #FUNCTION# =================================================================================================================== ; Name...........: _Subtract64 ; Description ...: Subtracts one integer from another. ; Syntax.........: _Subtract64($iOperand_1, $iOperand_2) ; Parameters.....; $iOperand_1 - The first operand. ; $iOperand_2 - The second operand. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@error = 1 The first parameter is not an integer. ; |@error = 2 The second parameter is not an integer. ; |@extended = 1 The result is limited to double precision. ; |@extended = 3 The result is out of range for Int-64. ; Author.........: czardas ; ============================================================================================================================== Func _Subtract64($iOperand_1, $iOperand_2) $iOperand_1 = __Integer64($iOperand_1) If @error Then Return SetError(1, 1, __DoubleTo64($iOperand_1 - $iOperand_2)) ; may still return an integer $iOperand_2 = __Integer64($iOperand_2) If @error Then Return SetError(2, 1, __DoubleTo64($iOperand_1 - $iOperand_2)) ; ditto Local $bOverflow, $nResult $bOverflow = __OverflowDetect('-', $iOperand_1, $iOperand_2, $nResult) Return SetExtended($bOverflow *3, $nResult) EndFunc ;==> _Subtract64 #Region - Internal Functions ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __DoubleTo64 ; Description ...: Helper function - converts an integer value double to Int-32 or Int-64. ; Syntax.........: __DoubleTo64($nValue) ; Parameters.....; $nValue - The double to convert ; Return values .: Success returns Int-32 or Int-64 when the interpreter evaluates the converted double equal to the input. ; Failure returns the input parameter without any modification and sets the following flags: ; |@error = 3 Internal error (x2) ==> see comments in the code. ; |@extended = 2 Conversion failed ==> the return value is not an integer. ; Author ........: czardas ; Comments ......; Doubles representing integer values greater than 15 digits cannot be relied on for accuracy. ; ============================================================================================================================== Func __DoubleTo64($nValue) If Not IsNumber($nValue) Then Return SetError(3, 2, $nValue) ; the input is not a number. If $nValue > -1.0e+015 And $nValue < 1.0e+015 Then Local $iVal64 = Number($nValue, 2) ; convert to Int-64 If $iVal64 = $nValue Then ; check to see if conversion was a success [expected range +/- 5.62949953421311e+014] Return ($iVal64 > 2147483647 Or $iVal64 < -2147483648) ? $iVal64 : Number($iVal64, 1) ; Int-64 or Int-32 ElseIf $iVal64 -1 = $nValue Then ; attempt to adjust for inaccuracies [subject to possible change] Return $iVal64 -1 ElseIf $iVal64 +1 = $nValue Then ; as above Return $iVal64 +1 EndIf EndIf Return SetError(3, 2, $nValue) ; conversion failed EndFunc ;==> __DoubleTo64 ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __Integer64 ; Description ...: Checks if a number is an integer and converts doubles to Int-32 or Int-64 if the result appears unambiguous. ; Syntax.........: __Integer64($nParam) ; Parameters.....; $nParam - The number to test ; Return values .: Success returns Int-32 or Int-64 when the interpreter evaluates the returned integer equal to the input. ; Failure returns the input parameter without any modification and sets the following flags: ; |@error = 1 The input is not an integer. ; |@extended = 2 The return value is not an integer. ; Author ........: czardas ; Comments ......; Doubles representing integer values greater than 15 digits cannot be relied on for accuracy. ; ============================================================================================================================== Func __Integer64($nParam) If Not StringInStr(VarGetType($nParam), 'Int') Then Local $iInt64 = __DoubleTo64($nParam) ; attempt conversion If @error Then Return SetError(1, 2, $nParam) ; $fParam <> $iInt64 $nParam = $iInt64 ; float was compared as being equal to an integer EndIf Return $nParam EndFunc ;==> __Integer64 ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __OverflowDetect ; Description ...: Checks for integer overflow on execution of the expression. ; Syntax.........: __OverflowDetect($sOperator, $iOperand_1, $iOperand_2, $nResult) ; Parameters.....; $sOperator - May be +, - or *. ; $iOperand_1 - The first operand. ; $iOperand_2 - The second operand. ; $nResult - [ByRef] Result of executed expression. ; Return values .: Returns True if integer overflow occurs - otherwise returns False. Returns $nResult ByRef. ; Author ........: czardas ; Comments ......; Int-32 or Int-64 only. No error checks! ; ============================================================================================================================== Func __OverflowDetect($sOperator, $iOperand_1, $iOperand_2, ByRef $nResult) Local $iExecute, $fCompare Switch $sOperator Case '+' ; execute the expression $iExecute = $iOperand_1 + $iOperand_2 ; execute the expression with the operands converted to doubles $fCompare = Number($iOperand_1, 3) + Number($iOperand_2, 3) Case '-' ; as above $iExecute = $iOperand_1 - $iOperand_2 $fCompare = Number($iOperand_1, 3) - Number($iOperand_2, 3) Case '*' ; as above $iExecute = $iOperand_1 * $iOperand_2 $fCompare = Number($iOperand_1, 3) * Number($iOperand_2, 3) EndSwitch ; the results should be approximately equal Local $bReturn = StringFormat('%.14e', $iExecute) <> StringFormat('%.14e', $fCompare) ; %.15e is too sensitive $nResult = $bReturn ? $fCompare : $iExecute Return $bReturn EndFunc ;==> __OverflowDetect ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __Product64($iOperand_1, $iOperand_2) ; Description ...: Helper function - multiplies two Int-32 or Int-64 values together. ; Syntax.........: __Product64($iOperand_1, $iOperand_2) ; Parameters.....; $iOperand_1 - The first integer. ; $iOperand_2 - The second integer. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@extended = 3 The result is out of range for Int-64. ; Author.........: czardas ; Comments ......; Int-32 or Int-64 only. No error checks! ; ============================================================================================================================== Func __Product64($iOperand_1, $iOperand_2) Local $bOverflow, $nResult $bOverflow = __OverflowDetect('*', $iOperand_1, $iOperand_2, $nResult) Return SetExtended($bOverflow *3, $nResult) EndFunc ;==> __Product64 ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __WholeNumberDivision ; Description ...: Divides two integers. ; Syntax.........: __WholeNumberDivision($iDividend, $iDivisor) ; Parameters.....; $iDividend - The first operand. ; $iDivisor - The second operand. ; Return values .: Returns an Int-32, or Int-64, value. ; Failure returns the executed expression and sets the following flags: ; |@extended = 1 The result is limited to double precision. ; |@extended = 2 The result is not an integer. ; |@extended = 4 The result is infinity. ; Author ........: czardas ; Comments ......; Input is limited to +/- 9223372036854775807 for both consitency and compatibility with future libraries. ; May return an integer with the extended flag set to 2 due to internal rounding. This is not a bug! ; ============================================================================================================================== Func __WholeNumberDivision($iDividend, $iDivisor) ; Input ranges -9223372036854775807 To 9223372036854775807 If $iDivisor = 0 Then Return SetExtended(4, $iDividend / $iDivisor) ; division by zero Local $aDiv = [$iDividend, $iDivisor], _ $iSign = 1 For $i = 0 To 1 If $aDiv[$i] > 0x7FFFFFFFFFFFFFFF Or $aDiv[$i] < 0x8000000000000001 Then Return SetExtended(1, $iDividend / $iDivisor) ; input range exceeded If $aDiv[$i] < 0 Then ; force positive integers $aDiv[$i] *= -1 $iSign *= -1 ; to add back later EndIf Next If Mod($aDiv[0], $aDiv[1]) Then Return SetExtended(2, $iDividend / $iDivisor) ; not divisible If $aDiv[0] = 0 Then Return 0 If $aDiv[1] = 1 Then Return $aDiv[0] * $iSign Local $iDivision = Floor($aDiv[0] / $aDiv[1]), $iDifference, $iIntegral While $iDivision * $aDiv[1] > $aDiv[0] ; division is overstated $iDifference = ($aDiv[1] * $iDivision) - $aDiv[0] $iIntegral = Floor($iDifference / $aDiv[1]) ; avoid shooting beyond the target If $iIntegral = 0 Then $iIntegral = 1 ; prevents hanging in an infinite loop $iDivision -= $iIntegral WEnd While $iDivision * $aDiv[1] < $aDiv[0] ; division is understated $iDifference = $aDiv[0] - ($aDiv[1] * $iDivision) $iIntegral = Floor($iDifference / $aDiv[1]) ; as above If $iIntegral = 0 Then $iIntegral = 1 ; prevents hanging $iDivision += $iIntegral WEnd Return $iDivision * $iSign EndFunc ;==> __WholeNumberDivision #EndRegion The following tests need updating because values for @error and @extended have changed. #include 'operator64.au3' ConsoleWrite("Testing _Abs64()" & @LF) ; ==> Err Ext Result $test = _Abs64(0xC000000000000000) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 4611686018427387904 $test = _Abs64(0x8000000000000000) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 2 1 9.22337203685478e+018 $test = _Abs64(0x8000000000000001) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 9223372036854775807 $test = _Abs64(-0.123) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 1 1 0.123 ;=========================================================== ConsoleWrite(@LF & "Testing _Add64()" & @LF) $test = _Add64(0x7FFFFFFFFFFFFFFF, 1) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 1 9.22337203685478e+018 $test = _Add64(0x7FFFFFFFFFFFFFFF, 0) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 9223372036854775807 $test = _Add64(0x7FFFFFFFFFFFFFFF, -1) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 9223372036854775806 $test = _Add64(33, 15) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 48 ;=========================================================== ConsoleWrite(@LF & "Testing _Divide64()" & @LF) $test = _Divide64(0x7FFFFFFFFFFFFFFF, -1) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 -9223372036854775807 $test = _Divide64(0x8000000000000000, -2) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 4611686018427387904 $test = _Divide64(10.0, 2) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 5 $test = _Divide64(9223372036854775552, -2) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 -4611686018427387776 $test = _Divide64(9223372036854775552, 0) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 2 1 1.#INF $test = _Divide64(675432.0097, -987) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 1 1 -684.328277304965 $test = _Divide64(6922337, 15) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 4 1 461489.133333333 ;=========================================================== ConsoleWrite(@LF & "Testing _Multiply64()" & @LF) $test = _Multiply64(9223372036854775552, -2) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 1 -1.84467440737096e+019 $test = _Multiply64(223372036854775552, 9) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 2010348331692979968 $test = _Multiply64(1.01, -1) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 1 1 -1.01 ;=========================================================== ConsoleWrite(@LF & "Testing _Power64()" & @LF) $test = _Power64(-2.0, 63) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 -9223372036854775808 $test = _Power64(37, 12.0) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 6582952005840035281 $test = _Power64(17, 19) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 1 2.39072435685151e+023 ;=========================================================== ConsoleWrite(@LF & "Testing _Subtract64()" & @LF) $test = _Subtract64(1.0, 1) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 0 $test = _Subtract64(0x8000000000000000, -1) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 -9223372036854775807 $test = _Subtract64(0x8000000000000000, 0) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 0 -9223372036854775808 $test = _Subtract64(0x8000000000000000, 1) ConsoleWrite(@Error & @TAB & @Extended & @TAB & $test & @LF) ; ==> 0 1 -9.22337203685478e+018It's nice to try and figure out something like this for yourself, but it would be quite impossible without the hints and advice I receive from others when I take a wrong turn sometimes. So thanks to those people.1 point
-
akira2891, Glad I could help. M231 point
-
akira2891, Of course it will not show anything - you keep overwriting the returned array as you test each drive, so there probably is nothing to display when you finally try to do so. Try this version: #include <Array.au3> #include <File.au3> #include <AutoItConstants.au3> Global $aArray = DriveGetDrive($DT_ALL), $file = "test.txt" If @error Then ; An error occurred when retrieving the drives. MsgBox(0, "Error retrieving the drives", "Error : " & @error & ", Extended : " & @extended) Else For $i = 1 To $aArray[0] $aFileList = _FileListToArrayRec($aArray[$i] & "\", $file, $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH) If Not @error Then _ArrayDisplay($aFileList, "FileList for " & $aArray[$i]) EndIf Next EndIfThat finds the files for me. Celtic88, Why reinvent the wheel? We have a perfectly good recursive search function so no need to write another. M231 point
-
Skysnake, Do not take it personally - it does it to lots of people all the time. I will fix the typo. M23 Edit: And done.1 point
-
KANIFUSA, Here you go: #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 888, 583, -1, -1) $Pic1_1 = GUICtrlCreatePic("form1.bmp", -0, -0,888, 583) GUICtrlSetState($Pic1_1, $GUI_DISABLE) $Button1_1 = GUICtrlCreateButton("Button GUI Form2", 240, 52, 205, 102) $Button1_2 = GUICtrlCreateButton("2", 448, 52, 100, 102) $Button1_3 = GUICtrlCreateButton("3", 564, 52, 101, 102) $Button1_4 = GUICtrlCreateButton("4", 668, 52, 101, 102) $Button1_5 = GUICtrlCreateButton("5", 772, 52, 101, 102) $Button1_6 = GUICtrlCreateButton("6", 240, 157, 101, 102) $Button1_7 = GUICtrlCreateButton("7", 344, 157, 101, 102) $Button1_8 = GUICtrlCreateButton("8", 448, 157, 100, 102) $Button1_9 = GUICtrlCreateButton("9", 564, 157, 101, 102) $Button1_10 = GUICtrlCreateButton("10", 668, 157, 101, 102) $Button1_11 = GUICtrlCreateButton("11", 772, 157, 101, 102) $Button1_12 = GUICtrlCreateButton("12", 240, 261, 205, 102) $Button1_13 = GUICtrlCreateButton("13", 448, 261, 100, 102) $Button1_14 = GUICtrlCreateButton("14", 564, 261, 101, 102) $Button1_15 = GUICtrlCreateButton("15", 668, 261, 205, 102) $Button1_16 = GUICtrlCreateButton("16", 240, 365, 205, 102) $Button1_17 = GUICtrlCreateButton("17", 448, 365, 100, 102) $Button1_18 = GUICtrlCreateButton("18", 564, 365, 101, 102) $Button1_19 = GUICtrlCreateButton("19", 668, 365, 101, 102) $Button1_20 = GUICtrlCreateButton("20", 772, 365, 101, 102) GUISetState(@SW_SHOW) $Form2 = GUICreate("Form2", 392, 623, -1, -1) $Pic2_1 = GUICtrlCreatePic("form2.bmp", 0, 0, 392, 623) GUICtrlSetState($Pic2_1, $GUI_DISABLE) $Button2_1 = GUICtrlCreateButton("Button GUI Form1", 56, 36, 325, 165) $Button2_2 = GUICtrlCreateButton("Button2", 72, 208, 145, 73) $Button2_3 = GUICtrlCreateButton("Button3", 224, 208, 145, 73) $Button2_4 = GUICtrlCreateButton("Button4", 72, 320, 145, 73) $Button2_5 = GUICtrlCreateButton("Button5", 224, 320, 145, 73) $Button2_6 = GUICtrlCreateButton("Button6", 72, 424, 145, 73) $Button2_7 = GUICtrlCreateButton("Button7", 224, 424, 145, 73) GUISetState(@SW_HIDE) While 1 $aMsg = GUIGetMsg(1) Switch $aMsg[1] Case $Form1 Switch $aMsg[0] Case $GUI_EVENT_CLOSE Exit Case $Button1_1 GUISetState(@SW_HIDE, $Form1) GUISetState(@SW_SHOW, $Form2) EndSwitch Case $Form2 Switch $aMsg[0] Case $GUI_EVENT_CLOSE Exit Case $Button2_1 GUISetState(@SW_HIDE, $Form2) GUISetState(@SW_SHOW, $Form1) EndSwitch EndSwitch WEndYou should read the http://www.autoitscript.com/wiki/Managing_Multiple_GUIs tutorial in the Wiki to understand what is going on. M231 point
-
I must be misunderstanding, creating variables with special characters seems to work fine. *my mistake was doing this with 3.3.10.2 assign("2^3" , execute(2^3)) assign("2*3" , execute(2*3) & " : SIX") assign("2+3" , "FIVE") assign("2-3" , execute(2-3)) msgbox(0, "2^3" , eval("2^3")) msgbox(0, "2*3" , eval("2*3")) msgbox(0, "2+3" , eval("2+3")) msgbox(0, "2-3" , eval("2-3")) and further playing assign(".-" , "A") assign("-..." , "B") assign("-.-." , "C") local $sOut = "" local $sString = ".- -... -.-." $aString = stringsplit($sString , " " , 2) for $i = 0 to ubound($aString) - 1 $sOut &= eval($aString[$i]) Next msgbox(0, $sString , $sOut)1 point
-
Check if chrome.exe is active
szucsaaron reacted to Danyfirex for a topic
to check for url look this Saludos1 point -
Thank you both. I thought I had stored ProgAndy's code somewhere on my PC. I had, in an unlikely place. His regexp seems to work for all formats of number: Func IsNumeric($vValue) Return (StringRegExp($vValue, "(^[+-]?[0-9]+\.?[0-9]*$|^0x[0-9A-Fa-f]{1,8}$|^[0-9]+\.?[0-9]*[Ee][+-][0-9]+$)") = 1) EndFunc ;==>_IsNumeric1 point
-
Hello, help me this error (TCP send picture )
SkythekidRS reacted to Celtic88 for a topic
you can send big file server TCPStartup() Global $ip = @IPAddress1 Global $Port = 4444 Global $sSocket = -1 Global $LenSendData = 1024 * 1024 Global $PackSendfile = "[PackSendfile]" Global $EndPackSendfile = "[EndPackSendfile]" Global $lenEndPackSendfile = StringLen($EndPackSendfile) Global $RecevFileok = "[RecevFileok]" Global $Spdata = "[#Spdata]" Global $listen = TCPListen($ip, $Port) Global $sSocket = _Tcp_Get_Connection($listen) While True Sleep(100) _Getcmdtype($sSocket) WEnd Func _Getcmdtype($tsSocket) Local $Getcmdtype = TCPRecv($tsSocket, 999) If $Getcmdtype = "" Then Return False Select Case StringInStr($Getcmdtype, $PackSendfile) > 0 Local $Getfileinfo = StringSplit($Getcmdtype, $Spdata, 1) If @error Then Return False Local $Filesize = $Getfileinfo[2] Local $cSavepath = FileSaveDialog("Choose a filename...", @WorkingDir, "All (*.*)", 18, "test") If @error Then Return _Tcp_Exit() MsgBox(0, "", _Getdisplaysize(_Tcp_Rcv_File($tsSocket, $Filesize, FileGetShortName($cSavepath))) & " it was rcv") _Tcp_Exit() EndSelect EndFunc ;==>_Getcmdtype Func _Tcp_Rcv_File($sSocket, $Filesize, $cSavepath) Local $op, $Binfile, $binlen, $Timer, $tbinlen, $ps TCPSend($sSocket, $RecevFileok) $op = FileOpen($cSavepath, 18) ProgressOn("Progress Meter", "Receive state", "Start",default,default,16) $Timer = TimerInit() Do $Binfile = "" Do $Binfile &= TCPRecv($sSocket, $LenSendData) Until StringRight($Binfile, $lenEndPackSendfile) = $EndPackSendfile $Binfile = StringSplit($Binfile, $EndPackSendfile, 1) $Binfile = $Binfile[1] $binlen += BinaryLen($Binfile) FileWrite($op, $Binfile) TCPSend($sSocket, $RecevFileok) If TimerDiff($Timer) >= 1000 Then $Rate = $binlen - $tbinlen $ps = ($binlen / $Filesize) * 100 $tbinlen = $binlen ProgressSet(Int($ps), "Receive " & _Getdisplaysize($binlen) & " Of " & _Getdisplaysize($Filesize) & " " & Int($ps) & " % Rate " & _Getdisplaysize($Rate)) $Timer = TimerInit() EndIf Until $Filesize = $binlen ProgressOff() FileClose($op) Return $binlen EndFunc ;==>_Tcp_Rcv_File Func _Tcp_Get_Connection($sSocketlisten) Local $stSocket Do $stSocket = TCPAccept($listen) Until $stSocket <> -1 Return $stSocket EndFunc ;==>_Tcp_Get_Connection Func _Tcp_Exit() TCPCloseSocket($listen) TCPCloseSocket($sSocket) TCPShutdown() Exit EndFunc ;==>_Tcp_Exit Func _Getdisplaysize($isize) If $isize < 1 Then Return 0 Local $abytes[5] = [' Bytes', ' Kb', ' Mb', ' Go', ' Tb'] For $i = 4 To 1 Step -1 If $isize >= 1024 ^ $i Then Return Round($isize / 1024 ^ $i, 1) & $abytes[$i] Next Return $isize & $abytes[0] EndFunc ;==>_Getdisplaysize client TCPStartup() Global $ip = @IPAddress1 Global $Port = 4444 Global $LenSendData = 1024 * 1024 Global $PackSendfile = "[PackSendfile]" Global $EndPackSendfile = "[EndPackSendfile]" Global $RecevFileok = "[RecevFileok]" Global $Spdata = "[#Spdata]" Global $Connect = _Tcp_Clien_Connect($ip, $Port) Global $mFilepath = FileOpenDialog("Select a file..", @WorkingDir & "\", "All (*.*)", 1) If Not @error Then MsgBox(0, "", _Getdisplaysize(_Tcp_Send_file($Connect, FileGetShortName($mFilepath))) & " it was sent") TCPCloseSocket($Connect) TCPShutdown() Func _Tcp_Send_file($stSocket, $mFilepath) Local $op, $Iread, $rcv, $binlen, $Filesize, $Timer, $tbinlen, $ps, $zError = False $Filesize = FileGetSize($mFilepath) TCPSend($stSocket, $PackSendfile & $Spdata & $Filesize) Do $rcv &= TCPRecv($stSocket, 24) Until $rcv = $RecevFileok $op = FileOpen($mFilepath, 16) ProgressOn("Progress Meter", "Send state", "Start",default,default,16) $Timer = TimerInit() While True $Iread = FileRead($op, $LenSendData) If @error Then ExitLoop TCPSend($stSocket, $Iread & $EndPackSendfile) $binlen += BinaryLen($Iread) $rcv = "" Do $rcv &= TCPRecv($stSocket, 24) Until $rcv = $RecevFileok If TimerDiff($Timer) >= 1000 Then $Rate = $binlen - $tbinlen $ps = ($binlen / $Filesize) * 100 $tbinlen = $binlen ProgressSet(Int($ps), "Sent " & _Getdisplaysize($binlen) & " Of " & _Getdisplaysize($Filesize) & " " & Int($ps) & " % Rate " & _Getdisplaysize($Rate)) $Timer = TimerInit() EndIf WEnd ProgressOff() FileClose($op) Return $binlen EndFunc ;==>_Tcp_Send_file Func _Tcp_Clien_Connect($sIp, $mPort) Local $sSocket Do Sleep(100) $sSocket = TCPConnect($sIp, $mPort) Until $sSocket <> -1 Return $sSocket EndFunc ;==>_Tcp_Clien_Connect Func _Getdisplaysize($isize) If $isize < 1 Then Return 0 Local $abytes[5] = [' Bytes', ' Kb', ' Mb', ' Go', ' Tb'] For $i = 4 To 1 Step -1 If $isize >= 1024 ^ $i Then Return Round($isize / 1024 ^ $i, 1) & $abytes[$i] Next Return $isize & $abytes[0] EndFunc ;==>_Getdisplaysize1 point -
Process Suspend/Process Resume UDF
GeneNight reacted to The Kandie Man for a topic
Well, I was looking on the internet for ways to suspend processes and spent a great deal of time trying to find API commands to do this. I found many thread suspend functions and other things, but not really any process suspend functions. I finally found a process suspend NTAPI function NtSuspendProcess(). To my great distaste I could find absolutely nothing documenting the NTAPI functions, nothing at all. Hours of Googling and i finally found a page that has the NTAPI functions listed. No thanks to Microsoft. :S You would think they would document functions that they took the time to write so that people could actually use them. To save others time, here is a page with the NTAPI functions listed: http://www.metasploit.com/users/opcode/syscalls.html Here is a UDF to call the system API to suspend or resume a process. No more systeminternals 104kb PsSuspend.exe. Func _ProcessSuspend($process) $processid = ProcessExists($process) If $processid Then $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $processid) $i_sucess = DllCall("ntdll.dll","int","NtSuspendProcess","int",$ai_Handle[0]) DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle) If IsArray($i_sucess) Then Return 1 Else SetError(1) Return 0 Endif Else SetError(2) Return 0 Endif EndFunc Func _ProcessResume($process) $processid = ProcessExists($process) If $processid Then $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $processid) $i_sucess = DllCall("ntdll.dll","int","NtResumeProcess","int",$ai_Handle[0]) DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle) If IsArray($i_sucess) Then Return 1 Else SetError(1) Return 0 Endif Else SetError(2) Return 0 Endif EndFunc @The Development Team I think it would be a good idea to add these to the process.au3 include file. You can call the function with the process name or PID _ProcessSuspend("notepad.exe") or _ProcessSuspend(467) The returns are as follows: 0 = Failure 1 = Sucess @error = 1 means that it failed because something errored when calling the dll @error = 2 means that it failed because the process was not found or is not running Sorry i didn't do a standard UDF writeup, didn't have time. If the development team is interested in adding this function i will happily write the standard UDF documentation for it. Important: This function will only run on Windows XP, Windows 2003 and Windows Vista.1 point -
Memory compression
Colduction reacted to trancexx for a topic
Appears that memory compression is in these days. So, to be in, here is another method. This one is called "Native API Compression". Apparently it's LZ1(LZ77) compression algorithm or something very similar and it's available through one or two dll calls. Of course that files can be compressed too by this method. Functions with small example: #NoTrayIcon $sString = "lzwlzwlzwlzwlzwlzwlzwlzwlzwlzwlzwlzw" ConsoleWrite("Before compression: " & Binary($sString) & @CRLF) $BC = _LZNTCompress($sString) ConsoleWrite("Compressed: " & $BC & @CRLF) $CB = _LZNTDecompress($BC) ConsoleWrite("Decompressed: " & $CB & @CRLF) ; #FUNCTION# ;=============================================================================== ; ; Name...........: _LZNTDecompress ; Description ...: Decompresses input data. ; Syntax.........: _LZNTDecompress ($bBinary) ; Parameters ....: $vInput - Binary data to decompress. ; Return values .: Success - Returns decompressed binary data. ; - Sets @error to 0 ; Failure - Returns empty string and sets @error: ; |1 - Error decompressing. ; Author ........: trancexx ; Related .......: _LZNTCompress ; Link ..........; http://msdn.microsoft.com/en-us/library/bb981784.aspx ; ;========================================================================================== Func _LZNTDecompress($bBinary) $bBinary = Binary($bBinary) Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinary) & "]") DllStructSetData($tInput, 1, $bBinary) Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]") ; initially oversizing buffer Local $a_Call = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _ "ushort", 2, _ "ptr", DllStructGetPtr($tBuffer), _ "dword", DllStructGetSize($tBuffer), _ "ptr", DllStructGetPtr($tInput), _ "dword", DllStructGetSize($tInput), _ "dword*", 0) If @error Or $a_Call[0] Then Return SetError(1, 0, "") ; error decompressing EndIf Local $tOutput = DllStructCreate("byte[" & $a_Call[6] & "]", DllStructGetPtr($tBuffer)) Return SetError(0, 0, DllStructGetData($tOutput, 1)) EndFunc ;==>_LZNTDecompress ; #FUNCTION# ;=============================================================================== ; ; Name...........: _LZNTCompress ; Description ...: Compresses input data. ; Syntax.........: _LZNTCompress ($vInput [, $iCompressionFormatAndEngine]) ; Parameters ....: $vInput - Data to compress. ; $iCompressionFormatAndEngine - Compression format and engine type. Default is 2 (standard compression). Can be: ; |2 - COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD ; |258 - COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM ; Return values .: Success - Returns compressed binary data. ; - Sets @error to 0 ; Failure - Returns empty string and sets @error: ; |1 - Error determining workspace buffer size. ; |2 - Error compressing. ; Author ........: trancexx ; Related .......: _LZNTDecompress ; Link ..........; http://msdn.microsoft.com/en-us/library/bb981783.aspx ; ;========================================================================================== Func _LZNTCompress($vInput, $iCompressionFormatAndEngine = 2) If Not ($iCompressionFormatAndEngine = 258) Then $iCompressionFormatAndEngine = 2 EndIf Local $bBinary = Binary($vInput) Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinary) & "]") DllStructSetData($tInput, 1, $bBinary) Local $a_Call = DllCall("ntdll.dll", "int", "RtlGetCompressionWorkSpaceSize", _ "ushort", $iCompressionFormatAndEngine, _ "dword*", 0, _ "dword*", 0) If @error Or $a_Call[0] Then Return SetError(1, 0, "") ; error determining workspace buffer size EndIf Local $tWorkSpace = DllStructCreate("byte[" & $a_Call[2] & "]") ; workspace is needed for compression Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]") ; initially oversizing buffer Local $a_Call = DllCall("ntdll.dll", "int", "RtlCompressBuffer", _ "ushort", $iCompressionFormatAndEngine, _ "ptr", DllStructGetPtr($tInput), _ "dword", DllStructGetSize($tInput), _ "ptr", DllStructGetPtr($tBuffer), _ "dword", DllStructGetSize($tBuffer), _ "dword", 4096, _ "dword*", 0, _ "ptr", DllStructGetPtr($tWorkSpace)) If @error Or $a_Call[0] Then Return SetError(2, 0, "") ; error compressing EndIf Local $tOutput = DllStructCreate("byte[" & $a_Call[7] & "]", DllStructGetPtr($tBuffer)) Return SetError(0, 0, DllStructGetData($tOutput, 1)) EndFunc ;==>_LZNTCompress Available in Microsoft Windows XP and later versions of all Windows operating systems. There is $tBuffer there if you look. I'm oversizing it plenty initially (saw this bad example in c++). Probably should be some better way to do that but documentation for this functions on MSDN is not over yet apparently Two compression rates are available. Default COMPRESSION_ENGINE_STANDARD is lightening speedy. Better compression is gained by COMPRESSION_ENGINE_MAXIMUM which is slower.1 point