2009-10-01 19 views
9

Devo eseguire una divisione in virgola mobile in un batch dos.Divisione in virgola mobile in un file batch

Non ho trovato il modo di farlo. Qualcosa del genere:

SET /A Res=10/3 

restituisce un numero intero.

È possibile farlo?

+0

Perché mai hai bisogno di fare questo? Hai considerato VBScript o qualche altro motore di scripting? –

+0

Ho lavorato su una libreria batch di bignum. Ancora molto incompiuto ancora, però. – Joey

+0

Nel caso in cui si sia ancora interessati a farlo con il puro batch. https://www.dostips.com/forum/viewtopic.php?t=3854 – Squashman

risposta

5

I file batch non supportano l'aritmetica in virgola mobile. Tuttavia, this article suggerisce una soluzione alternativa che utilizza un file di script esterno per eseguire calcoli. Il file di script deve utilizzare una sorta di funzione eval per valutare l'espressione passata come argomento e restituire il risultato. Ecco un esempio di file VBScript (eval.vbs) che fa questo:

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

È possibile chiamare questo script esterno dal file batch, specificare l'espressione da valutare e ottenere il risultato di nuovo. Per esempio:

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

Naturalmente, si otterrà il risultato come una stringa, ma è meglio di niente in ogni caso, e si può passare il risultato ottenuto allo script eval come parte di un'altra espressione.

+0

Non è possibile passare il risultato a un altro script eval, almeno nel caso generale. I numeri sono formattati per le impostazioni locali correnti. Nel mio caso ciò significa che la virgola ',' è usata come punto decimale. Questo porta a un errore di sintassi se dovessi inserire nuovamente il risultato nello script. – Joey

3

Secondo this reference, non c'è tipo a virgola mobile in linguaggio batch DOS:

Sebbene esistano variabili nel linguaggio di programmazione in batch DOS, essi sono estremamente limitate. Non ci sono tipi di variabili interi, puntatori o in virgola mobile, solo stringhe.

Penso che ciò che si sta tentando di fare sarà impossibile senza implementare il proprio schema di divisione per calcolare il resto in modo esplicito.

+3

Anche se sono solo stringhe, è possibile eseguire l'aritmetica dei numeri interi a 32 bit con 'set/a'. – Joey

2

Recentemente ho trovato questo file batch per calcolare un'approssimazione di Pi. C'è un'etichetta DivideByInteger che potrebbe essere utile: Stupid-Coding-Tricks-A-Batch-of-Pi

Si utilizza un insieme di MaxQuadIndex variabili, ciascuno contenente un numero di quattro cifre (quadrupla), per memorizzare l'intero risultato. Il codice consente la divisione di un numero intero compreso tra 1 e 10000 inclusi.

: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 

Un Print etichetta è disponibile anche ...

2

provare questo

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 

basta cambiare

chiamata: calc_ decimalpoint equataion

nell'esempio

decimalpoint è 1

equataion è (99- (100 * 5/100 ^) ^); assicurarsi se si utilizza(), che si inserisce^prima) come in ^)

la risposta è 94,0

se decimalpoint è 2

e equataion è 22/7; π pi

la risposta è 3.14

6

So che questo è un argomento molto vecchio, ma non riesco a trovare un semplice metodo Batch in tutte le risposte precedenti, quindi inserisco qui una soluzione Batch pura che è molto semplice da usare.

Eseguire operazioni utilizzando l'aritmetica in virgola fissa in Batch è semplice. "Punto fisso" significa che è necessario impostare un numero di decimali in anticipo e mantenerlo durante tutte le operazioni. Aggiungere e sottrarre le operazioni tra due numeri a Punto Fisso direttamente. Le operazioni di moltiplicazione e divisione richiedono una variabile ausiliaria, che possiamo chiamare "una", con il valore di 1 con il numero corretto di decimali (come cifre "0"). Dopo averlo moltiplicato, dividi il prodotto per "uno"; prima della divisione, moltiplica il dividendo per "uno". Eccolo:

@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%! 

Ad esempio:

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 
+0

Molto buono! Non so come questa non sia la risposta accettata in quanto è molto semplice; moltiplicare un numero intero per 10000 per ottenere altri 4 decimali e così via. – Gustavo6046

0

ho scritto un file batch pura appositamente per fare la divisione. Prende il primo numero immesso, quindi lo divide per il secondo e visualizza il risultato con tutti i decimali specificati.

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 

La risposta inserita nella variabile% Ans%. Può anche essere chiamato con parametri. ("Divide.bat 50 27 5" ti darebbe 50/27 su 5 punti decimali.)

Problemi correlati