Victor Chavez
Victor Chavez

Reputation: 59

How to make random number variable with variables within it?

So I've been trying to make the following code:

set /a num1=10
set /a num2=%random% %%60 +%num1%
echo %num2%

(This is simplified)

For this code I need the +%num1% to be a variable because I need to be able to change the lowest number.

For some reason, instead of giving me a random number it gives a totally unrelated number, that isn't random either, but the same every time. My first thought was it was perhaps adding the second variable instead of making a randomizer. That is not the case though, and I'm not sure how to fix this issue.

I have also tried the following code:

set /a num1=10
set /a num2=(%random%*60/32768)+%num1%
echo %num2%

The issue with this code is it never seems to work as randomizer for me even without the variable.

Any help is appreciated.

Upvotes: 0

Views: 381

Answers (2)

Ben Personick
Ben Personick

Reputation: 3264

  1. In the first form you are have to account for modulus bias, as described further in this question Why do people say there is modulo bias when using a random number generator?

(Note: the accepted answer there has a flaw which I pointed out and provide a solution to in my answer to that question.)

  1. In both the first and the second form they present an incorrect range of values the way it is written. More info can be found here How to use random in BATCH script?

Long story Short:

In both forms, if you want your range to start at 10 and go to 60 you will need to adjust it to be using a modulus of 50, in the first form you must account for modulus bias in your calculations causing some numbers to appear more often.

The first form can be fixed using this method:

SET "Min=10"
SET "Max=60"
SET /A "Discard= 32768 - ( ( ( 32768 %% (Min-Max) ) + 1 ) %% (Min-Max) )"
:Rand
  SET /A "num2=%random%"
  IF %num2% GTR %Discard% GOTO :Rand
SET /A "num2= num2 %% (Min-Max) + Min"
echo=%num2%

The second form can be fixed using this method:

SET "Min=10"
SET "Max=60"
SET /A "num2= %random% * ( Max - Min + 1 ) / 32768 + Min "
echo=%num2%

Example of Full script:

@(SETLOCAL
  ECHO OFF
)

CALL :Main

( ENDLOCAL
  EXIT /B
  pause
)

:Main
  SET "Min=10"
  SET "Max=60"
  SET /A "Discard= 32768 - ( ( ( 32768 %% (Min-Max) ) + 1 ) %% (Min-Max) )"
  ECHO=Form1:
  CALL :Form1
  ECHO=Form2:
  CALL :Form2
  pause

GOTO :EOF

:Form1
  SET "num2=%random%"
  IF %num2% GTR %Discard% GOTO :Form1
  SET /A "num2= num2 %% ( Min - Max ) + Min"
  echo=%num2%
GOTO :EOF

:Form2
  SET /A "num2= %random% * ( Max - Min + 1 ) / 32768 + Min "
  echo=%num2%
GOTO :EOF

Results:

C:\WINDOWS\system32>C:\Admin\SE\testrandom.cmd
Form1:
10
Form2:
31
Press any key to continue . . .

C:\WINDOWS\system32>

Upvotes: 0

Compo
Compo

Reputation: 38614

Here's some examples to assist you:

Set "num1=10"
Set /A "num2 = (%RANDOM% %% 60) + num1"
Echo(%num2%
Set "num1=10"
Set /A "num2 = (%RANDOM% * 60 / 32768) + num1"
Echo(%num2%

Please note, that we have only been provided with a very small portion of your batch file, so if this code is part of a parenthesized block, you may need to enable delayed expansion and use !RANDOM! and possibly !num2! instead of %RANDOM% and %num2% respectively.

Upvotes: 1

Related Questions