# Solved: Random Number Batch Generator - Just for practice



## scrfix

Hello,

This is just practice merely to increase my batch writing skills, I have taken what I have learned here (and am comfortable with) and I decided to write a random number generator. Nobody really even needs to comment. I am merely interested if it is decent. If someone needs a random number generator here it is. There is no project here or time frame. Just me studying. I am merely wondering whether or not this is the best way to accomplish this task or if I am way off base here:

The original basis for this was because I was studying more about batch file commands and found the following webpage: http://archive.atomicmpc.com.au/forums.asp?s=2&c=10&t=3221

The third post in reply to the original question and tells the person to put some numbers into some variables and then he gives a mathematical equation however that didn't really look that random to me because he was putting actual numbers within his bat file. If you are going to set static numbers, why not just use %random% because that is all you are essentially doing other than the mathematics? So I thought I would make this useless program that is actually 100% random. It can help me learn and I can see just how decent (or not so much) that I really am thus far. The mathematical algorithm can be changed to whatever to make it more random.

Is this the easiest method?
Is there a better solution?

*See update below this original code. There is newer, more updated code*

*Original Code*


Code:


@echo off
set /a number=0
If %number% LSS 1234 Call :_RandomNumber
echo Random Number Using Algorithm: %number%
echo Random Number Using Windows built-in Random variable: %random%
Goto _End
 
:_RandomNumber
:_setmax
set /a max=%random%
if %max% LSS 1234 GOTO _setmax
 
:_setmin
set /a min=%random%
set /a min=%min:~0,4%
if %min% LSS 1 GOTO _setmin
if %min% GEQ 8000 GOTO _setmin
 
:_setrange
set /a range=%max%-%min%
 
:_setmaxrand
set /a maxrand=%random%
if %maxrand% LSS 10000 GOTO _setmaxrand
 
:_setminrand
set /a minrand=%random%
if %minrand% LSS 1 GOTO _setminrand
if %minrand% GEQ 10000 GOTO _setminrand
 
:_setrangerand
set /a rangerand=%maxrand%-%minrand%
 
:_setrand
set /a rand=%random%
set /a rand=%rand:~0,1%
if %rand% LSS 1 GOTO _setrand
if %rand% GEQ 3 GOTO _setrand
 
:_setnumber
set /a number=(((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^^ %rand%))
if %number% LSS 1234 Call :_RandomNumber
if %number% GEQ 1234 GOTO :Eof
 
:_End
pause

*Update 12:24am EST 07-02-09*

I did find a more efficient way of performing this task however I attempted with setLocal EnableDelayedExpansion and it kept failing on me. It kept telling me I was missing the operator so I changed my random numbers from set /a min=!random!%%7999 to set /a min=%random%%7999 and I took out the setLocal and EndLocal statements.

Here is the new code should anyone need a random number generator.


Code:


@echo off
set /a number=0
If /i %number% LSS 1234 Call :_RandomNumber
echo Random Number Using Algorithm: %number%
echo Random Number Using Windows built-in Random variable: %random%
Goto _End
 
:_RandomNumber
 
:_setmax
set /a max=%random%
if %max% LSS 8000 GOTO _setmax
 
:_setmaxrand
set /a maxrand=%random%
if %maxrand% LSS 10000 GOTO _setmaxrand
 
set /a min=%random%%%7999
set /a range=%max%-%min%
set /a minrand=%random%%%9999
set /a rangerand=%maxrand%-%minrand%
set /a rand=%random%%%3
set /a number=(((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^^ %rand%))
if %number% LSS 1234 Call :_RandomNumber
GOTO :EOF
 
:_End
pause


----------



## TheOutcaste

That certainly adds a bit more randomness to the number.
Just want to point out that the */A* is not really needed on these lines:
Line 3 - set */a* number=0
Line 12 - set */a* max=%random%
Line 16 - set */a* maxrand=%random%
Since right side will always be a number, and is not a formula, it's not needed. Doesn't hurt to be there, but makes no difference in this case.

The */i* isn't needed in the If statement as numbers don't have case.
Line 4 - If */i* %number% LSS 1234 Call :_RandomNumber

If you put quotes around the expression you don't need to escape the caret symbol in line 24
set /a number="(((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^ %rand%))"
You also don't need to use the surrounding percent symbols when using /A, so this will also work:
set /a number="(((random - minrand) * range) / ((rangerand + min) ^ rand))"

Jerry


----------



## scrfix

Thanks Jerry,

I was actually wondering about the /a however I remember somewhere that you had mentioned to me put the /a because it is a number so I kept it in there. I did test it without it however and it did work find.

The quotes I had no idea about. Why is that?

The () around the whole thing. Without them I kept getting unbalanced parenthesis error.


----------



## TheOutcaste

I suggested using Set /A where you are asking a user to type in a number.


Code:


Set /P _Resp="Enter a number"
If %_Resp% LEQ 10 Echo You entered a number less than 10.

If they just press enter, the IF statement will fail. If you use Set /A, it will convert the null entry to 0. No need to check for a null entry, or having to quote both sides of the condition if you can accept pressing Enter as zero.


Code:


Set /P _Resp="Enter a number"
Set /A _Resp=_Resp
If %_Resp% LEQ 10 Echo You entered a number less than 10

It can also be used to remove leading spaces from a number.

Some of the special characters are treated as regular characters when they appear between quotes:
Compare these lines:


Code:


Echo This string ^ has a Special Character
Echo "This string ^ has a Special Character"
Echo This string ^ has some | Special Characters
Echo "This string ^ has some | Special Characters"
Echo This string & has some | Special Characters
Echo "This string & has some | Special Characters"

If you don't want the quotes, you have to escape the characters.
Works with redirection characters as well


Code:


Echo This string has a Special Char>acter

This will create a file named *acter* in the current directory that contains the string *This string has a Special Char*


Code:


Echo "This string has a Special Char>acter"

This will output the line to the screen.

I didn't try changing the parentheses until now. I removed the outermost pair, and both of these work for me, as did removing the outermost pair for the dividend:


Code:


set /a number=((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^^ %rand%)
set /a number="((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^ %rand%)"
set /a number="(%random% - %minrand%) * %range% / [COLOR=Red]([/COLOR](%rangerand% + %min%) ^ %rand%[COLOR=Red])[/COLOR]"

If you remove the outermost pair from the divisor, it will still work, but it changes the formula. Without those parentheses, the division will be done first, then the XOR will be done to the result as XOR has a lower precedence.


----------



## ghostdog74

scrfix said:


> Hello,
> 
> This is just practice merely to increase my batch writing skills, I have taken what I have learned here (and am comfortable with) and I decided to write a random number generator. Nobody really even needs to comment. I am merely interested if it is decent. If someone needs a random number generator here it is. There is no project here or time frame. Just me studying. I am merely wondering whether or not this is the best way to accomplish this task or if I am way off base here:
> 
> The original basis for this was because I was studying more about batch file commands and found the following webpage: http://archive.atomicmpc.com.au/forums.asp?s=2&c=10&t=3221
> 
> The third post in reply to the original question and tells the person to put some numbers into some variables and then he gives a mathematical equation however that didn't really look that random to me because he was putting actual numbers within his bat file. If you are going to set static numbers, why not just use %random% because that is all you are essentially doing other than the mathematics? So I thought I would make this useless program that is actually 100% random. It can help me learn and I can see just how decent (or not so much) that I really am thus far. The mathematical algorithm can be changed to whatever to make it more random.
> 
> Is this the easiest method?
> Is there a better solution?
> 
> *See update below this original code. There is newer, more updated code*
> 
> *Original Code*
> 
> 
> Code:
> 
> 
> @echo off
> set /a number=0
> If %number% LSS 1234 Call :_RandomNumber
> echo Random Number Using Algorithm: %number%
> echo Random Number Using Windows built-in Random variable: %random%
> Goto _End
> 
> :_RandomNumber
> :_setmax
> set /a max=%random%
> if %max% LSS 1234 GOTO _setmax
> 
> :_setmin
> set /a min=%random%
> set /a min=%min:~0,4%
> if %min% LSS 1 GOTO _setmin
> if %min% GEQ 8000 GOTO _setmin
> 
> :_setrange
> set /a range=%max%-%min%
> 
> :_setmaxrand
> set /a maxrand=%random%
> if %maxrand% LSS 10000 GOTO _setmaxrand
> 
> :_setminrand
> set /a minrand=%random%
> if %minrand% LSS 1 GOTO _setminrand
> if %minrand% GEQ 10000 GOTO _setminrand
> 
> :_setrangerand
> set /a rangerand=%maxrand%-%minrand%
> 
> :_setrand
> set /a rand=%random%
> set /a rand=%rand:~0,1%
> if %rand% LSS 1 GOTO _setrand
> if %rand% GEQ 3 GOTO _setrand
> 
> :_setnumber
> set /a number=(((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^^ %rand%))
> if %number% LSS 1234 Call :_RandomNumber
> if %number% GEQ 1234 GOTO :Eof
> 
> :_End
> pause
> 
> *Update 12:24am EST 07-02-09*
> 
> I did find a more efficient way of performing this task however I attempted with setLocal EnableDelayedExpansion and it kept failing on me. It kept telling me I was missing the operator so I changed my random numbers from set /a min=!random!%%7999 to set /a min=%random%%7999 and I took out the setLocal and EndLocal statements.
> 
> Here is the new code should anyone need a random number generator.
> 
> 
> Code:
> 
> 
> @echo off
> set /a number=0
> If /i %number% LSS 1234 Call :_RandomNumber
> echo Random Number Using Algorithm: %number%
> echo Random Number Using Windows built-in Random variable: %random%
> Goto _End
> 
> :_RandomNumber
> 
> :_setmax
> set /a max=%random%
> if %max% LSS 8000 GOTO _setmax
> 
> :_setmaxrand
> set /a maxrand=%random%
> if %maxrand% LSS 10000 GOTO _setmaxrand
> 
> set /a min=%random%%%7999
> set /a range=%max%-%min%
> set /a minrand=%random%%%9999
> set /a rangerand=%maxrand%-%minrand%
> set /a rand=%random%%%3
> set /a number=(((%random% - %minrand%) * %range%) / ((%rangerand% + %min%) ^^ %rand%))
> if %number% LSS 1234 Call :_RandomNumber
> GOTO :EOF
> 
> :_End
> pause


why don't you just learn vbscript


Code:


'seed 
Randomize
max=100
min=1
' Generate number between 1 and 100
rand=Int((max - min + 1) * Rnd + min)
WScript.Echo rand


----------



## TheOutcaste

A batch file can generate a random number between specified limits just as easily


Code:


Set max=100
Set min=1
:: Generate number between Min and Max
Set /A rand=%random% %% (max - min + 1)+ min
Echo %rand%

You must have missed the whole point of what he's trying to do though, because he's _not_ trying to generate a random number between specified limits.


----------



## ghostdog74

TheOutcaste said:


> Echo %rand%[/code]You must have missed the whole point of what he's trying to do


i know batch can generate random numbers. but it doesn't have a seed. (does it?). With vbscript, you can initialize a seed value. I am not really interested in the whole what he is doing because i fully know that he can do the same the vbscript , that's why i had advised him to learn vbscript. I also fully know that my little snippet doesn't do what he want, (its just a demo to OP that he can do random gen with vbscript as well) but after learning vbscript, it can easily done.


----------



## scrfix

Ghostdog,

Thanks for your reply. The original post on here actually answers your question. This was a request from another forum that I was utilizing just to sharpen my batch writing skills. I have a bunch of computers that come to me everyday that I am attempting to make my job easier on for items I have to perform. I wanted to take what someone else wrote and make it better. I do understand about VB and there are some advantages and disadvantages to utilizing vbscript that I won't get into here. I do write some vbscript and 13 other programming/scripting langauges. I am by far not an expert at vbscript as it is my weakest language at this time.

You can actually utilize the following in batch script if you want a random number between 0-100. You do not have to have everything that I wrote above.



Code:


@echo off
set /a rand=%random%%%100
echo %rand%
pause

%random% will actually set a number from 0 - 32675 (Is that correct Jerry, I did not check reference. Purely from memory.). If you would like to limit what it looks at you can add the %%number-here. It will now only look from 0 - 100 as shown above.

However aside from all of that, this whole post was merely to sharpen my batch writing skills. Writing in VB would defeat the purpose of the initial post. Hope that answers your question.


----------



## TheOutcaste

scrfix said:


> %random% will actually set a number from 0 - 32675 (Is that correct Jerry, I did not check reference. Purely from memory.)


Close, 32767. It's a 15 bit number, so 2^15 - 1
And keep in mind that MOD returns the remainder, so A mod B returns 0 through (B-1), so the above will return 0-99, not 1-100.


----------



## scrfix

Thanks Jerry.

I was in a hurry and did not have time to look it up. Completely forgot about the 0 - 99.


----------

