Следующая строка кода выполняется через мой текущий проект:

set /a "hp = hp - ((atk*arandom)/((edef*6)/edefbonus))"

А вот как это выглядит, когда вы заменяете переменные их значениями:

set /a "hp = 50 - ((2*2)/((1*6)/8))"

Ответ на это 44.666667, который должен быть округлен до 45. Но вместо этого Batch просто говорит мне "Ошибка деления на ноль" при запуске кода, как с версией, которая использует переменные, так и с версией, которая использует вместо этого числа.

Я действительно потерян для подсказок. Я проверил наличие неравных скобок, я проверил наличие неустановленных переменных и установлен EnabledDelayedExpansion. Так что я делаю не так ...?

3 ответа3

2

Если нет причины делить знаменатель на edfbonus вместо умножения на него числителя, вы можете избежать проблемы делителя нуля, переставив вычисления:

set /a "hp = hp - ((atk*arandom*edefbonus)/(edef*6))"

Внешние скобки и кавычки не нужны, и в set /a есть оператор, который сохраняет некоторые операции ввода и приводит в порядок такие выражения:

set /a hp -= atk*arandom*edefbonus/(edef*6)

Так как вы упомянули округление, я добавлю это:

При условии, что значение справа от оператора -= выше всегда положительно, самый простой способ выполнить округление:

set /a hp -= (10*atk*arandom*edefbonus/(edef*6)+5)/10

Обратите внимание, что мы умножаем на 10 до деления, а не после него, поэтому вычисление идет следующим образом:

10*2*2*8 =320
1*6      =6
320/6    =53
53+5     =58
58/10    =5

Если мы умножим на 10 после деления, как в

set /a hp -= (atk*arandom*edefbonus/(edef*6)*10+5)/10 ,

расчет будет идти:

2*2*8 =32
1*6   =6
32/6  =5   (we just lost the fraction digit, so rounding won't work)
5*10  =50
50+5  =55
55/10 =5

Тот же результат, но только потому, что округление все равно было бы округлено вниз.

1

Пакет не может обрабатывать числа с плавающей запятой, только целые числа.

Итак ((1*6)/8) = 0 вместо 0.75 . Затем вы пытаетесь разделить (2*2) на этот 0 , что приводит к ошибке "Делить на ноль".

Предлагаемое решение? Вместо этого используйте PowerShell:

PS Y:\> $hp = 50 - ((2*2)/((1*6)/8))
PS Y:\> $hp
44.6666666666667

Связанный вопрос SU:

Связанный ТАК вопрос:

1

Пакетная операция возвращает "Ошибка деления на ноль"

set /a "hp = 50 - ((2*2)/((1*6)/8))"

Это потому, что 1*6 = 6 и 6/8 = 0.75 .

А также:

Любое вычисление SET /A, которое возвращает дробный результат, будет округлено до ближайшего целого числа.

Таким образом, 0.75 округляется до 0 .

6/0 возвращает "Ошибка деления на ноль".


обходные

Нет реальных обходных путей, позволяющих использовать математику с плавающей запятой, кроме использования других языков сценариев.

Единственным исключением может быть, если у вас ограниченное и фиксированное количество десятичных знаков (например, 2), тогда вы можете просто умножить все на 100.

Чтобы отобразить десятичный разделитель в конечных результатах, объедините целочисленное деление на 100, затем десятичный разделитель и деление по модулю на 100:

SET Whole = Result / 100
SET "Fraction = Result %% 100"
SET Result=%Whole%.%Fraction%

Это может нарушить 32-битный лимит.

В целом, для математики с плавающей точкой я бы рекомендовал использовать другие языки сценариев.

Исходный Math в пакетных файлах NT


Арифметические выражения (SET /a)

Поместить выражения в "кавычки" необязательно для простой арифметики, но необходимо для любого выражения, использующего логические операторы.

Любое вычисление SET /A, которое возвращает дробный результат, будет округлено до ближайшего целого числа.

Исходный набор


Дальнейшее чтение

  • Индекс AZ командной строки Windows CMD - Отличный справочник по всем вопросам, связанным с командной строкой Windows.
  • set - отображать, устанавливать или удалять переменные окружения CMD. Изменения, сделанные с помощью SET, будут сохраняться только в течение текущего сеанса CMD.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .