czardas Posted February 3, 2015 Share Posted February 3, 2015 One would assume that this is either a fluke or possibly an undocumented feature. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jaberwacky Posted February 3, 2015 Share Posted February 3, 2015 (edited) I don't understand this function _MathCheckDiv. Why not use Mod($n1, $n2) = 0? Func Divisible(Const $n1, Const $n2) Return Mod($n1, $n2) = 0 EndFunc Edited February 3, 2015 by jaberwacky Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
czardas Posted February 3, 2015 Share Posted February 3, 2015 (edited) I always do use Mod() personally. Edited February 3, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jaberwacky Posted February 3, 2015 Share Posted February 3, 2015 Works with floats too? That just occurred to me. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
JohnOne Posted February 3, 2015 Author Share Posted February 3, 2015 Perhaps the function is redundant then, maybe created before Mod() was introduced? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
czardas Posted February 3, 2015 Share Posted February 3, 2015 I consider it redundant. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted February 8, 2015 Share Posted February 8, 2015 (edited) I've been thinking this function should remain in Math.au3 for at least two reasons: Firstly because it's easier for people who are less mathematically inclined, and secondly because it's likely already being used in many scripts; although personally, I've only seen it used in a few. Following jaberwacky's suggestion to use Mod(), here's a new version. I think the return values are strange, but maybe that's just me. ; Func _MathCheckDiv_2($iNum1, $iNum2 = 2) If Not (IsInt($iNum1) And IsInt($iNum2)) Then Return SetError(1, 0, -1) Return (Mod($iNum1, $iNum2) = 0) ? 2 : 1 EndFunc ;==>_MathCheckDiv_2 ; Mod() still needs testing for limits - if that's feasible. Preliminary tests suggest Mod may work up to 9223372036854775806, but proving this by rigorous testing is not really feasible. ; Local $iMax = 9223372036854775806 For $i = $iMax to $iMax - 100 Step - 1 ConsoleWrite((_MathCheckDiv_2($i) = 2) & @LF) Next Func _MathCheckDiv_2($iNum1, $iNum2 = 2) If Not (IsInt($iNum1) And IsInt($iNum2)) Then Return SetError(1, 0, -1) Return (Mod($iNum1, $iNum2) = 0) ? 2 : 1 EndFunc ;==>_MathCheckDiv_2 ; I found the above value through trial and error. If I add 1 to that value it becomes 0x7FFFFFFFFFFFFFFF. So I can tell you categorically that Mod() does not work beyond Int-64. After one or two more tests, it appears Mod() has worked for all Int-64 values I've tried. It's still not safe to assume it always will work on the grounds of so few tests, but the results are promising. I'll throw a few large primes in and see what happens. Edited February 8, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted February 17, 2015 Share Posted February 17, 2015 (edited) I said I would throw some primes at this and I'm happy with the results. expandcollapse popup;#include <Array.au3> ; Testing Int64 compatible version of _MathCheckDiv() Func _MathCheckDiv($iNum1, $iNum2 = 2) If Not (IsInt($iNum1) And IsInt($iNum2)) Then Return SetError(1, 0, -1) Return (Mod($iNum1, $iNum2) = 0) ? 2 : 1 EndFunc ;==>_MathCheckDiv Local $iIterations = 25 Local $aPrime[$iIterations][2], $aProduct[$iIterations], $i0, $i1 ; Generate random primes for testing. For $i = 0 To $iIterations -1 $i0 = Random(7, 12, 1) ; number of digits in the first prime $i1 = 18 - $i0 ; number of digits in the second prime $aPrime[$i][0] = _RandomPrime($i0) $aPrime[$i][1] = _RandomPrime($i1) $aProduct[$i] = $aPrime[$i][0] * $aPrime[$i][1] ; Int64 Sleep(50) ; We are generating large primes Next _ClearDivisors() ;_ArrayDisplay($aPrime) ; Basically this checks that Mod() works on the generated Int64 numbers. For $i = 0 To $iIterations -1 ; The following commented out line tests for non-divisible values. ; $aPrime[$i][0] += Random(1, 2, 1) ConsoleWrite( "_MathCheckDiv(" & $aProduct[$i] & ", " & $aPrime[$i][0] & ") ;==> " & _MathCheckDiv($aProduct[$i], $aPrime[$i][0])) ConsoleWrite(" " & $aProduct[$i] & " / " & $aPrime[$i][0] & " = " & $aProduct[$i] / $aPrime[$i][0] & @LF ) Next #Region - UDF ; #FUNCTION# ==================================================================================================================== ; Name...........: _ClearDivisors ; Description ...: Used to clear memory after calling _IsPrime() or _RandomPrime() ; Syntax.........: _ClearDivisors() ; Author ........: czardas ; Comments ......; Call this function if you no longer need to use _IsPrime() or _RandomPrime() and want to clear memory. ; =============================================================================================================================== Func _ClearDivisors() _IsPrime("", True) EndFunc ;==> _ClearDivisors ; #FUNCTION# ==================================================================================================================== ; Name...........: _IsPrime ; Description ...: Tests a number for primality. ; Syntax.........: _IsPrime($iInt [, _ClearDivisors = False]) ; Parameters ....: $iInt - The number to test ; : $bClearDivisors - DO NOT USE THIS PARAMETER ; Return values .: Success - Returns True, or False if not prime. ; Failure - Returns False and sets @error to 1 if $iInt is not an integer or is out of range: ; Author ........: czardas ; Comments ......; This function is designed to be called multiple times but uses lots of memory. ; ; It is advisable to use Sleep() after any batch processes to allow the CPU to cool off a little. ; ; After using this function you should free memory by calling the function _ClearDivisors() ; =============================================================================================================================== Func _IsPrime($iInt, $bClearDivisors = False) Static $aDivisors = __GetDivisors() If $bClearDivisors Then $aDivisors = 0 Return ElseIf Not IsArray($aDivisors) Then $aDivisors = __GetDivisors() EndIf If Not IsInt($iInt) Then Return SetError(1, 0, False) ; Only integers are allowed $iInt = Abs($iInt) If $iInt = 2 Or $iInt = 3 Or $iInt = 5 Or $iInt = 7 Or $iInt = 11 Or $iInt = 13 Then Return True If $iInt < 2 Or Not (Mod($iInt, 2) And Mod($iInt, 3) And Mod($iInt, 5) And Mod($iInt, 7) And Mod($iInt, 11) And Mod($iInt, 13)) Then Return False Local $bPrime = True, $iRoot = Sqrt($iInt) If IsInt($iRoot) Then Return False $iRoot = Floor($iRoot) For $i = 0 To 5759 For $j = $aDivisors[$i] To $iRoot Step 30030 ; 2 *3 *5 *7 *11 *13 If Mod($iInt, $j) Then ContinueLoop ; $j is not a factor $bPrime = False ExitLoop 2 Next Next Return $bPrime EndFunc ;==> _IsPrime ; #FUNCTION# ==================================================================================================================== ; Name...........: _RandomPrime ; Description ...: Returns a random prime number of between 1 and 15 digits in length (length must be specified). ; Syntax.........: _RandomPrime($iDigits) ; Parameters ....: $iDigits - The number of digits in the random prime number ; Return values .: Success - Returns a random prime number with the required number of digits. ; Failure - Sets @error to 1 if $iDigits is not an integer or is out of range: ; Author ........: czardas ; Comments ......; This function is designed to be called multiple times but uses lots of memory. ; ; It is advisable to use Sleep() after any batch processes to allow the CPU to cool off a little. ; ; After using this function you should free memory by calling the function _ClearDivisors() ; =============================================================================================================================== Func _RandomPrime($iDigits) If Not IsInt($iDigits) Or $iDigits < 1 Or $iDigits > 15 Then Return SetError(1) $iDigits -= 1 Local $iNumber = Number(Random(1, 9, 1) & StringMid(Random(), 3, $iDigits)) Local $iStep = 1 -2*Random(0, 1, 1) Local $aRange[15][2] = [[2,7],[11,97],[101,997],[1009,9973],[10007,99991],[100003,999983], _ [1000003,9999991],[10000019,99999989],[100000007,999999937],[1000000007,9999999967], _ [10000000019,99999999977],[100000000003,999999999989],[1000000000039,9999999999971], _ [10000000000037,99999999999973],[100000000000031,999999999999989]] If $iNumber > $aRange[$iDigits][1] And $iStep = 1 Then $iNumber = $aRange[$iDigits][0] ElseIf $iNumber < $aRange[$iDigits][0] And $iStep = -1 Then $iNumber = $aRange[$iDigits][1] EndIf While 1 ; Do not increase the size of the next loop. For $iNumber = $iNumber To $iNumber + 10*$iStep Step $iStep If _IsPrime($iNumber) Then ExitLoop 2 Next Sleep($iDigits + 16) ; CPU needs to cool down. WEnd Return $iNumber EndFunc ;==> _RandomPrime ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __GetDivisors ; Description ...: Sieve to remove prime multiples from the number range 17 to 30045. ; Syntax.........: __GetDivisors() ; Return values .: Success - Returns an array of the remaining numbers within the range. ; Author ........: czardas ; Comments ......; This function is called internally by _IsPrime ; =============================================================================================================================== Func __GetDivisors() Local $aPrimes[5] = [3,5,7,11,13], $aNumbers[15015], $iTemp For $i = 0 To 15014 $iTemp = $i*2 +17 ; Produces odd numbers from 17 to 30045 For $j = 0 To 4 If Not Mod($iTemp, $aPrimes[$j]) Then ContinueLoop 2 ; Skip multiples of 3, 5, 7, 11 and 13 Next $aNumbers[$i] = $iTemp Next $iTemp = 0 Local $aDivisors[5760] ; Will only contain the factors that made it through the sieve. For $i = 0 To 15014 If $aNumbers[$i] Then $aDivisors[$iTemp] = $aNumbers[$i] $iTemp += 1 EndIf Next Return $aDivisors EndFunc ;==> __GetDivisors #EndRegion Edited February 17, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
JohnOne Posted February 17, 2015 Author Share Posted February 17, 2015 At the very least, it should probably be noted in the help file that the function only accepts integer types. czardas 1 AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
jchd Posted June 10, 2015 Share Posted June 10, 2015 Why all those concern about Mod()?Anyway and beyond the fact that this function is a complete idiocy (including the dividend default and the returned values), input parameters can also be allowed to be integers in string form, thus the tests for IsInt are a waste. Using Int() on inputs would make more sense. And making the return value a boolean would have been wise (Jeez).Anyway, the following code works as specified and expected in the release (even stringed integers), but the beta fails when inputs are stringed ints or when divisor = 0#include <Math.au3> ConsoleWrite(_MathCheckDiv(123456, 3) & @LF) ConsoleWrite((Mod(123456, 3) ? 1 : 2) & @LF) ConsoleWrite((Mod(Int("123456"), Int("3")) ? 1 : 2) & @LF) Local $res = _MathCheckDiv("123456", "3") ConsoleWrite("Error = " & @error & ", returns " & $res & @LF & @LF) ConsoleWrite(_MathCheckDiv(123457, 3) & @LF) ConsoleWrite((Mod(123457, 3) ? 1 : 2) & @LF) ConsoleWrite((Mod(Int("123457"), Int("3")) ? 1 : 2) & @LF) $res = _MathCheckDiv("123457", "3") ConsoleWrite("Error = " & @error & ", returns " & $res & @LF & @LF) $res = _MathCheckDiv(1, 0) ConsoleWrite("Error = " & @error & ", returns " & $res & @LF) This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
czardas Posted June 10, 2015 Share Posted June 10, 2015 (edited) Hmm, my (script breaking) mistake: I didn't realise that strings were originally allowed in this function.I agree with you on the return values being silly. I also mentioned this when I submitted the changes, but nobody agreed (nor did they disagree). What exactly would you have happen when the divisor = 0? Surely an error is the most sensible return value here, or would you rather the function return True because all numbers are divisible by zero an infinite number of times? - Confusing! Oops! Edited June 10, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jchd Posted June 10, 2015 Share Posted June 10, 2015 Let's see: ConsoleWrite(VarGetType(1/0) & " : " & 1/0 & @LF) gives Double : 1.#INFNo, no integer is divisible by zero (division by zero is not allowed in the integers) so of course an error should result. You probably meant that zero is divisible by any non-zero integer, that is 0/x = 0 is true for any x <> 0The (minor) issue with the (mad) return value is that making it a boolean would break a few (silly) scripts, but I wouldn't cry for long should that occur. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
czardas Posted June 10, 2015 Share Posted June 10, 2015 (edited) I thought that result 1.#INF meant infinity. Division by zero was a success: in that it gave an appropriate answer. I would rather an undefined boolean return, but that doesn't exist in AutoIt. Perhaps it is simply a meaningless result.Func _MathCheckDiv($iNum1, $iNum2) $iNum1 = Int($iNum1) $iNum2 = Int($iNum2) If $iNum2 = 0 Then Return SetError(1, 0, False) ; This return value worries me. Return Mod($iNum1, $iNum2) = 0 ; True or False EndFunc ;==>_MathCheckDiv Edited June 10, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jchd Posted June 10, 2015 Share Posted June 10, 2015 Infinity is not an integer nor a real value and it represents a failure here. Null can (should probably) be that value but it isn't used at all in std functions return values. czardas 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
czardas Posted June 10, 2015 Share Posted June 10, 2015 (edited) Okay thanks jchd. Null would be better from my perspective too. Edited June 10, 2015 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jchd Posted June 10, 2015 Share Posted June 10, 2015 In my view Null is the best return value in case of error, meaning "can't deliver a meaningful result" or "no data in this result", quite similarly to what Null means in SQL (yes, again, I know, I know!). Others may object since Null is relatively recent and has been little used openly AFAIK. Its advantage is that it isn't itself any computable type (string, int, double, boolean, ...) even if it can be converted into one. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
czardas Posted June 10, 2015 Share Posted June 10, 2015 There seem to be no issues with using Null, I'll definately start doing this in my own projects. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jchd Posted June 10, 2015 Share Posted June 10, 2015 Null is the best return value in case of errorAt least when no more sensible result form is available, like in our case. Now for instance when a function is supposed to return an array but, while no actual error occured, there is nothing to populate the returned array then I'd like to get an empty array instead of an error. From this point of view, there is a lot of discrepancies in the conventions used along the various functions and UDFs. But it's way too late for v3, must await v4 for that... This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
czardas Posted June 10, 2015 Share Posted June 10, 2015 Null doesn't behave exactly like an undefined boolean. I think (Not Undefined) = Undefined. Anyway I still approve of your suggestions. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted June 14, 2015 Share Posted June 14, 2015 Why all those concern about Mod()?It is justified to check the functions you use actually do what you think they do. Mod() has undergone changes over time and I didn't know it's limitations. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now