Деление с плавающей точкой в ​​пакетном файле - PullRequest
13 голосов
/ 01 октября 2009

Мне нужно выполнить деление с плавающей запятой в пакете DOS.

Я не нашел способ сделать это. Примерно так:

SET /A Res=10/3

возвращает целое число.

Возможно ли это сделать?

Ответы [ 6 ]

8 голосов
/ 01 марта 2015

Я знаю, что это очень старая тема, но я не могу найти простой Batch-метод во всех предыдущих ответах, поэтому я публикую здесь простое Batch-решение, которое очень просто в использовании.

Выполнять операции с использованием арифметики с фиксированной точкой в ​​пакетном режиме просто. «Фиксированная точка» означает, что вы должны заранее установить количество десятичных знаков и сохранять их на протяжении всей операции. Операции сложения и вычитания между двумя номерами с фиксированной точкой выполняются напрямую. Операции умножения и деления требуют вспомогательной переменной, которую мы можем назвать «один», со значением 1 с правильным количеством десятичных знаков (как цифры «0»). После умножения разделите произведение на «один»; перед делением умножьте дивиденд на «один». Вот оно:

@echo off
setlocal EnableDelayedExpansion

set decimals=2

set /A one=1, decimalsP1=decimals+1
for /L %%i in (1,1,%decimals%) do set "one=!one!0"

:getNumber
set /P "numA=Enter a number with %decimals% decimals: "
if "!numA:~-%decimalsP1%,1!" equ "." goto numOK
echo The number must have a point and %decimals% decimals
goto getNumber

:numOK
set numB=2.54

set "fpA=%numA:.=%"
set "fpB=%numB:.=%"

set /A add=fpA+fpB, sub=fpA-fpB, mul=fpA*fpB/one, div=fpA*one/fpB

echo %numA% + %numB% = !add:~0,-%decimals%!.!add:~-%decimals%!
echo %numA% - %numB% = !sub:~0,-%decimals%!.!sub:~-%decimals%!
echo %numA% * %numB% = !mul:~0,-%decimals%!.!mul:~-%decimals%!
echo %numA% / %numB% = !div:~0,-%decimals%!.!div:~-%decimals%!

Например:

Enter a number with 2 decimals: 3.76
3.76 + 2.54 = 6.30
3.76 - 2.54 = 1.22
3.76 * 2.54 = 9.55
3.76 / 2.54 = 1.48
6 голосов
/ 01 октября 2009

Пакетные файлы как таковые не поддерживают арифметику с плавающей запятой. Однако в этой статье предлагается обходной путь, который использует внешний файл сценария для выполнения вычислений. Файл сценария должен использовать какую-то функцию eval для оценки выражения, переданного в качестве аргумента, и возврата результата. Вот пример файла VBScript ( eval.vbs ), который делает это:

WScript.Echo Eval(WScript.Arguments(0))

Вы можете вызвать этот внешний скрипт из вашего пакетного файла, указать выражение для оценки и получить результат обратно. Например:

@echo off
for /f %%n in ('cscript //nologo eval.vbs "10/3"') do (
  set res=%%n
)
echo %res%

Конечно, вы получите результат в виде строки, но в любом случае это лучше, чем ничего, и вы можете передать полученный результат в сценарий eval как часть другого выражения.

3 голосов
/ 01 октября 2009

Согласно этой ссылке , в языке пакетной обработки DOS нет типа с плавающей запятой:

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

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

2 голосов
/ 12 декабря 2013

попробуйте

SETLOCAL EnableExtensions EnableDelayedExpansion
call :calc_ 1 (99-(100*5/100^)^)
echo !calc_v!
goto :EOF
:calc_
set scale_=1
set calc_v=
for /l %%i in (1,1,%1) do set /a scale_*=10
set /a "calc_v=!scale_!*%2"
set /a calc_v1=!calc_v!/!scale_!
set /a calc_v2=!calc_v!-!calc_v1!*!scale_!
set calc_v=!calc_v1!.!calc_v2!
goto :EOF

просто изменить

вызов: calc_ десятичная точка экватора

в примере

десятичная точка 1

равно (99- (100 * 5/100 ^) ^); убедитесь, что вы используете (), который вставляете ^ ранее), как в ^)

ответ 94.0

если десятичная точка равна 2

и экватион 22/7; π pi

ответ 3.14

2 голосов
/ 22 марта 2011

Я недавно наткнулся на этот пакетный файл, чтобы вычислить приближение числа Пи. Существует ярлык DivideByInteger, который может быть вам полезен: Stupid-Coding-Tricks-A-Batch-of-Pi

Используется набор MaxQuadIndex переменных, каждая из которых содержит четырехзначное число (четверка), чтобы сохранить весь результат. Код допускает деление на целое число от 1 до 10000 включительно.

:DivideByInteger
    if defined PiDebug echo.DivideByInteger %1 %2
    set /a DBI_Carry = 0
    for /L %%i in (!MaxQuadIndex!, -1, 0) do (
        set /a DBI_Digit = DBI_Carry*10000 + %1_%%i
        set /a DBI_Carry = DBI_Digit %% %2
        set /a %1_%%i = DBI_Digit / %2
    )
    goto :EOF

A Print этикетка также доступна ...

1 голос
/ 09 октября 2015

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

Echo off
cls
if NOT "%3" == "" (
set n1=%1
set n2=%2
set max=%3
goto :begin
)

set counter=2
set n1=1
set n2=1
set ans=
:start
Echo.
Echo. 1 / 2
Echo.
Set /p N1= 1?
set /p N2= 2?
Set /p Max= Out how many Decimal Points?
:begin
set /a TmpAns=%N1%/%N2%
set ans=%TmpAns%.
:: Echo.%ans%.>Answer.txt
<nul set /p "=%Tmpans%."
set /a TmpSub=%N2%*%TmpAns%
set /a N1=%N1%-%TmpSub%
set N1=%N1%0
If NOT "%n1%" == "00" (
if %n1% LSS %N2% (
set N1=%N1%0
set ans=%ans%0
)
) else (
Goto :Finished
)
set count=0

:loop
If "%count%" == "%max%" (
Goto :Finished
)

set /a TmpAns=%N1%/%N2%
set ans=%ans%%TmpAns%
<nul set /p "=%Tmpans%"
set /a TmpSub=%N2%*%TmpAns%
set /a N1=%N1%-%TmpSub%
set N1=%N1%0
If NOT "%n1%" == "00" (
if %n1% LSS %N2% (
set N1=%N1%0
set ans=%ans%0
)
) else (
Goto :Finished
)
set /a count=%count%+1
goto :loop

:finished
cls
Echo.
Echo.
Echo.The Number
Echo.%ans%
Echo.
Echo.
set n1=1
set n2=1
pause
goto :eof

:eof

Ответ помещается в переменную% Ans%. Его также можно вызывать с параметрами. («Divide.bat 50 27 5» даст вам 50/27 из 5 десятичных знаков.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...