2013-04-07 3 views
2

Я пытаюсь создать случайную переменную от 0 до 3 с помощью командного файла. Прямо сейчас у меня есть следующий код:Случайные переменные в пакетных файлах

@echo off 
set /a var=%random%/8192 
@echo %var% 
Pause 

Этот командный файл возвращает «2» каждый раз. Если я печатаю те же команды в командной строке непосредственно она возвращает 0 до 3.

Любые соответствующие знания будут оценены :)

+0

У меня нет этой проблемы. Попробуйте вынуть '@' перед '@echo% var%'? Хотя это действительно ничего не должно меняться ... – Zyerah

+1

Ваш код генерирует случайное число от 0 до 3; правильной формулой будет: 'set/a var =% random%/6554'. Однако формула _standard_ намного понятнее (см. Мой ответ ниже). – Aacini

ответ

3

EDIT: Я изменил мой ответ, потому что ОП изменил свой вопрос: изначально диапазон желаемых случайных чисел было 0 до 4 ...

Правая формула:

set /a var=%random% * 4/32768 

использование других операторов вместо (например,/или%) изменяет распределение случайных чисел, поэтому вы получите повторяющийся результат чаще, чем с помощью правильной формулы.

EDIT: Дополнительные пояснения добавил

Предыдущий код должен корректно работает в вашем примере выше. Однако, если ваш код помещен в код код (прилагается в круглых скобках), вы должны использовать Delayed Expansion (как указывали другие лица в своих ответах) в все переменные, которые могут быть изменены внутри блока, включая RANDOM.Например:

@echo off 
setlocal EnableDelayedExpansion 
:ProgStart 
(
set /a var = !random! * 4/32768 
goto target!var! 
) 

Если вы хотите, вы можете использовать эту простую формулу, которая дает эквивалентные результаты (случайные числа от 0 до 3):

set /a var = !random!/8192 
+0

Это 4 не 5 и 32768/4 = 8192. Его команда правильная, только в сокращенной форме. – rojo

+1

@rojo: Op хочет «создать случайную переменную от 0 до 4», а «% RANDOM% - расширяется до случайного десятичного числа от 0 до 32767» (взято из 'set /?'). Это означает, что% random%/8192 создает случайное число от 0 до 3 (попробуйте: 'set/a 32767/8192'). – Aacini

+0

Вы, конечно, правы. Извини за это. На данный момент у меня есть малыш, который не может обновить мой ответ. Если вы согласны с моим объяснением о том, почему его код имеет разные результаты при выполнении сценария cmd и пакетного сценария, не стесняйтесь копировать/вставлять его из моего ответа, так что хотя бы один ответ на этот взорванный поток рассмотрит все проблемы, продемонстрированные оператором. :) +1 заблаговременно. – rojo

1

Я думаю, вы используете% случайных% внутри блока if или for кода. В этом случае вам нужны delayed expansion и! Переменные! вместо% переменных%. Пример:

@echo off & setlocal enabledelayedexpansion 
for /l %%i in (1,1,5) do (
    echo %random% !random! 
) 
1

Modulo работает очень хорошо в этой ситуации:

set /a ran=%random% %% 4 + 1 

%ran% установлен ли в число от 1 до 4. Однако, это работает только в пакетном файле.

В командной строке вам потребуется:

set /a num=%random% % 4 + 1 
1

Ваш код хорошо. Однако у меня есть подозрение. В вашем полном скрипте вы set var и проверьте его значение в цикле for или if? Если это так, когда вы проверяете значение %var%, результат будет таким, какой ваш скрипт унаследовал бы как значение переменной среды %var%, вероятно, задержка в тестировании вашей командной строки вне сценария.

Если моя оценка истинна, тогда вам нужны setlocal enabledelayedexpansion и echo !var!. В противном случае for или if будет оценивать %var% со значением, которое оно содержало в то время for или if.

+0

Да, я использую Var с if заявлениями позже в моем коде, но с этим изменением я все еще получаю ту же проблему. Правильно ли я это реализую? @echo от SETLOCAL enabledelayedexpansion :!!!!! ProgStart набора/с варом = случайным/8192 если вар == 0 Гото target0 если вар == 1 Готы target1 если вар ==! 2 goto target2 if! Var! == 3 goto target3 – Nick

+0

@ user2053067: Могу ли я предложить вам просмотреть мой ответ? ... Спасибо – Aacini

1

Фактическая команда, которую вы хотите есть:

set /a var=%random% %% 4 

Это даст вам: 0, 1, 2 или 3.

Если вы делаете это внутри использование для цикла .. - т! ype вместо переменных% ..% - type, и в этом случае вам также понадобится setlocal enabledelayedexpansion где-то рядом с началом вашего пакетного файла.

Смежные вопросы