Jump to content

Why Random(10, 10, 1) returns 0 and set @error?


 Share

Recommended Posts

This isn't mathematically true, as my previous posts show and as fundamental logic dictates: there is $n want it or not.

To further convince yourself, imagine you have to pick a random card in a deck. If the deck contains only the Queen of spades, your choice will be ... the Queen of spades.

Well, unless you put extroardinary bad faith in it and declare you pick none because you're gay and don't have use for a Queen, or something.

Edited by jchd

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 here
RegExp tutorial: enough to get started
PCRE 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

  • 1 year later...

Also Add IsInt for those technical people!!!

 

But then the random() would fail on floats ;)

You'd need something like...

Func _Domran($Min=0,$Max=1,$Flag=0,$Inclusive=false)
    Local $res, $stringMode = False, $boolMode = False

    ; If only supplying 1 parameter, assume it is Max (and assume Min is zero)
    If (@NumParams = 1) Then
        $Max = $Min
        $Min = 0
    EndIf

    ; Oh boy, we're doing strings.
    If (IsString($Min) And IsString($Max)) Then
        $Min = String($Min)
        $Max = String($Max)

        ; Better limit it to single-character strings.
        ; I mean, a 'random' between "Hello" and "World" makes no sense, unless including a dictionary file - even then, what to choose?
        ; I don't know.  The code doesn't know.    Set @error, @extended = -2, result is an empty string.
        If ((StringLen($Min) > 1) Or (StringLen($Max) > 1)) Then
            Return SetError(1,-2,"")
        EndIf

        ; Cast the strings to integers
        $Min = AscW($Min)
        $Max = AscW($Max)

        ; Better make sure the random function doesn't do its Float thing.
        $Flag = 1

        ; Yep, we're in string mode.
        $stringMode = True
    ElseIf (IsString($Min) Or IsString($Max)) Then
        ; No! Bad! No mixing ambiguous types!
        ; Although 'random("A",9)' is technically valid, is the 9 supposed to be "9", or a {TAB}?
        ; I don't know.  The code doesn't know.  Set @error, @extended = -3, result is an empty string.
            Return SetError(1,-3,"")
    EndIf

    ; Really?  We're random'ing between Booleans now?
    If (IsBool($Min) And IsBool($Max)) Then
        ; Oh well, why not.
        $Min = 0
        $Max = 1
        $Flag = 1
        $boolMode = True
    ElseIf (IsBool($Min) Or IsBool($Max)) Then
        ; No! Listen!
        ; Although 'random(0,true)' is technically valid, what to return - a boolean or an int?
        ; I don't know.  The code doesn't know.  Set @error, @extended = -4, result is -1
        Return SetError(1,-4,2)
    EndIf

    ; Better limit things from here to Ints and/or Floats
    If ((IsInt($Min) Or IsFloat($Min)) And (IsInt($Max) Or IsFloat($Max))) Then
        ; Alright, here's the big one.  If Min equals Max, just set the result to Max.
        ; None of this 'run random() and check for error' stuff*
        If ($Min = $Max) Then
            $res = $Max
        Else
            ; And the other gotcha, Max being less than Min.
            If ($Max < $Min) Then
                ; Swap 'm around!
                ; Yeah, you could use math, but you just know somebody's gonna hit it up with 9223372036854775807 or something.
                Local $t = $Min
                $Min = $Max
                $Max = $t
            EndIf

            ; Alright, everything's sorted out now, we can safely call Random.  Right?
            ; Oh dang, forgot about that Inclusive thing.  Alright, here. we. go!
            If (($Flag = 0) And $Inclusive) Then
                ; You'd think you'd be able to overflow a float with addition, right?
                ; I tried.  I failed.  Hit it!
                Local $MaxAndASmidgen = $Max + 0.00000001

                ; The odds of Domran(0.0,1.0,0,True) actually hitting 1.0 exactly (well, the float representation of it) is negligible, but possible.
                ; Almost as negligible as the odds of a long period of values generated between 1.0 and 1.001.
                ; ( Here be unlikely dragons. )
                Do
                    $res = Random($Min,$MaxAndASmidgen)
                Until $res <= $Max
            Else
                $res = Random($Min,$Max,$Flag)
            EndIf
        EndIf
    Else
        ; If the input at this point isn't Ints and/or Floats (Binary? Pointer? Elephant?), what to do?
        ; I don't know.  The code doesn't know.  Set @error, @extended = -1, result is -1@.#IND
        return SetError(1,-1,0/0)
    EndIf

    If ($stringMode) Then
        ; Alright, if we're in string mode, return a new string character based on the result.
        return ChrW($res)
    ElseIf ($boolMode) Then
        ; If we're in boolean mode, return appropriate boolean.
        If ($res = 0) Then
            Return False
        Else
            Return True
        EndIf
    Else
        ; Otherwise, the result as is.
        return $res
    EndIf
    ; This thing is horrible.
EndFunc

; Test function.
#include <String.au3> ; _StringRepeat
Func RRTest($sTestname,$val1=0,$val2=1,$Flag=0,$Inclusive=false)
    Local $seed = @MSEC, $res, $err, $ext
    ConsoleWrite($sTestname & @LF)
    SRandom($seed)
    If (@NumParams = 1) Then
        $res = Random()
        $err = @error
        ConsoleWrite("Random (0): " & $res & _StringRepeat(@TAB,Ceiling(4 - (StringLen($res) / 8))) & "@error: " & $err & @LF)
        SRandom($seed)
        $res = _Domran()
        $err = @error
        $ext = @extended
        ConsoleWrite("Domran (0): " & $res & _StringRepeat(@TAB,Ceiling(4 - (StringLen($res) / 8))) & "@error: " & $err & @TAB & "@extended: " & $ext & @LF)
    ElseIf (@NumParams = 2) Then
        $res = Random($val1)
        $err = @error
        ConsoleWrite("Random (1): " & $res & _StringRepeat(@TAB,Ceiling(4 - (StringLen($res) / 8))) & "@error: " & $err & @LF)
        SRandom($seed)
        $res = _Domran($val1)
        $err = @error
        $ext = @extended
        ConsoleWrite("Domran (1): " & $res & _StringRepeat(@TAB,Ceiling(4 - (StringLen($res) / 8))) & "@error: " & $err & @TAB & "@extended: " & $ext & @LF)
    Else
        $res = Random($val1,$val2,$Flag)
        $err = @error
        ConsoleWrite("Random: " & $res & _StringRepeat(@TAB,Ceiling(4 - (StringLen($res) / 8))) & "@error: " & $err & @LF)
        SRandom($seed)
        $res = _Domran($val1,$val2,$Flag,$Inclusive)
        $err = @error
        $ext = @extended
        ConsoleWrite("Domran: " & $res & _StringRepeat(@TAB,Ceiling(4 - (StringLen($res) / 8))) & "@error: " & $err & @TAB & "@extended: " & $ext & @LF)
    EndIf
    ConsoleWrite(@LF)
    ; My new computer is too fast making $seed not change between calls. Slow down, boy!
    Sleep(1)
EndFunc

; Examples / tests
ConsoleWrite("Random vs _Domran output:" & @LF)
RRTest("Float between 0 (implied) and 1 (implied)")
RRTest("Float between 0 (implied) and 10",10)
RRTest("Float between -10 and 0 (implied) - Random doesn't do this, as it assumes -10 is Max and Min is 0. Max < Min is a no-no.",-10)
RRTest("Float between 10 and 10 - Random doesn't do this - /topic/138677",10,10)
RRTest("Float between 10 and 0 - Random doesn't do this. Max < Min is a no-no",10,0)
RRTest("Float between -10 and 10",-10,10)
RRTest("Float between 10 and -10 - Random doesn't do this. Max < Min is a no-no",10,-10)
RRTest("Float between 0 and 1.0 inclusive (Domran will differ from Random, but might actually hit 1.0! (you'd be so lucky)",0,1,0,True)
RRTest("Integer between -10 and 10",-10,10,1)
RRTest("Integer between 10 and 10 - Random doesn't do this - /topic/138677",10,10,1)
RRTest("Integer between 10 and -10 - Random doesn't do this. Max < Min is a no-no",10,-10,1)
RRTest("Letter between A and Z - Random doesn't do letters","A","Z")
RRTest("Letter between z and a - Random doesn't do letters","z","a")
RRTest("Something between A and 1 - Random thinks we're doing a float (see Datatypes topic), Domran declares it a no-no.","A",1)
RRTest("Something between Hello and World - Nope.","Hello","World")
RRTest("State between True and False - Random doesn't do Booleans",True,False)
RRTest("State between False and True - Random returns a Float here as it interprets False = 0, True = 1",False,True)
RRTest("Something between False and 1 - Random returns a Float, Domran sets error.",False,1)
RRTest("Something between a Binary and another Binary - No-go in either.",Binary(0),Binary(1))

ConsoleWrite(@LF)

ConsoleWrite("Time for some benchmarking (10,000 runs)" & @LF)
SRandom(0)
Local $iStart = TimerInit()
For $i = 1 To 10000
    Random(Random(0,10),Random(0,10))
Next
ConsoleWrite("Random (ms): " & TimerDiff($iStart) & @LF)

sRandom(0)
$iStart = TimerInit()
For $i = 1 To 10000
    _Domran(Random(0,10),Random(0,10))
Next
ConsoleWrite("Domran (ms): " & TimerDiff($iStart) & " (Ouch.)" & @LF)

ConsoleWrite(@LF & @LF)

; * (asterisk)
ConsoleWrite("Some more minimal benchmarking (100,000 runs) of checking for Random() error vs checking for equality before Random():" & @LF)
Func _RandomErrorcheck($min,$max)
    Local $res = Random($min,$max)
    If (@error) Then
        return $min
    Else
        return $res
    EndIf
EndFunc
Func _RandomEquality($min,$max)
    If ($min = $max) Then
        return $min
    Else
        return Random($min,$max)
    EndIf
EndFunc
SRandom(0)
$iStart = TimerInit()
For $i = 1 To 100000
    _RandomErrorcheck(1,2)
Next
ConsoleWrite("Checking for error on Random 1,2 (ms): " & TimerDiff($iStart) & @LF)
SRandom(0)
$iStart = TimerInit()
For $i = 1 To 100000
    _RandomEquality(1,2)
Next
ConsoleWrite("Checking for equality on Random 1,2 (ms): " & TimerDiff($iStart) & @LF)
SRandom(0)
$iStart = TimerInit()
For $i = 1 To 100000
    _RandomErrorcheck(2,2)
Next
ConsoleWrite("Checking for error on Random 2,2 (ms): " & TimerDiff($iStart) & @LF)
SRandom(0)
$iStart = TimerInit()
For $i = 1 To 100000
    _RandomEquality(2,2)
Next
ConsoleWrite("Checking for equality on Random 2,2 (ms): " & TimerDiff($iStart) & @LF)

( Don't mean to revive the thread - I understand *why* Random(n,n,1) doesn't return n, though it caught me off-guard when I encountered it, this was the first on-topic result found - glad the beta docs have this gotcha pointed out as well. )

Link to comment
Share on other sites

That means in particular: ∀ x ∊ ℤ, x ≤ x ≥ x

 

For all x that is a member of integer, x must be in this range: x <= x >= x.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

I wouldn't call it a quirk, I would say users should read carefully the documentation.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

I wouldn't call it a quirk, I would say users should read carefully the documentation.

Except until recently, the documentation didn't mention anything about this "quirk".

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Except until recently, the documentation didn't mention anything about this "quirk".

This.  And, unless a new release was made available in the last 2 weeks or so, the documentation that mentions this quirk is the beta release, not the version you'd reach straight from the site.

Of course if it's recommended to use the beta, perhaps that's what should be served up :)

( Alternatively, the old documentation adjusted for modifications in it that apply to the regular version and do not rely on the beta. )

 

I posted a very simple workaround function to the random 'quirk' back in 2010, >bottom of the first post.

 

Ah, I did not run into that post while searching.  This thread's title may be descriptively more attractive to the search (and I didn't search any further after hitting this one) :)

At least your solution is the right one (speed-wise - vs checking for @error after calling Random).

Of course that does leave the other quirks.. Max < Min being the more likely to encounter one.

Link to comment
Share on other sites

Of course that does leave the other quirks.. Max < Min being the more likely to encounter one.

 

Actually, czardas posted one that accounts for all of those >here.

Edited by willichan
Link to comment
Share on other sites

I wouldn't call it a quirk, I would say users should read carefully the documentation.

 

I like calling it a quirk because it fits the definition, "an individual peculiarity of character".  To many of us, it is a peculiar behavior.   :huh2:

I also choose to call it a quirk, because it was a design choice, and therefore not a "bug".

Link to comment
Share on other sites

Sorry to interrupt.  Math noob here.  How can x be greater than x?

i dont think anyone said anythign about x being greater than x. it was more along the lines of, if you have random do 10 as the minimum and 11 as the max, it will either pick 11 or 10. since random includes the limits as a result, why wouldnt 10 being the min and 10 being the max just return 10?

Link to comment
Share on other sites

what is a random number?
it is a number that you do not know which one will be.
So, if you ask to a random() function to return a number, you expect a random number
if you try to fool the function by asking a number that can not properly be random, the function rightly refuse to provide that number so as not to be a liar (and fooled). otherwise the function would not be true to herself!

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

i dont think anyone said anythign about x being greater than x.

 

JCHD said this: "For any x in the set of signed integers, (x is smaller or equal to x) and (x is greater or equal to x)."

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...