61} How can one devise a command line calculator?
There are several options. A fairly trivial, but severely limited
option is using the SET /A command. For example
@echo off & setlocal enableextensions
set /a x=4+7
echo %x%
endlocal & goto :EOF
The output would be
D:\TEST>cmdfaq
11
A second option is using G(nu)AWK. For example
@echo off & setlocal enableextensions
gawk 'BEGIN{printf"%%s\n",4/7}'
endlocal & goto :EOF
The output would be
D:\TEST>cmdfaq
0.571429
This option could be used to perform quite complicated calculations.
Of course, one could also have
@echo off & setlocal enableextensions
::
set find_=gawk.exe
set found_=
for %%f in ("%find_%") do set found_="%%~$PATH:f"
if exist "%find_%" set found_="%find_%"
if [%found_%]==[""] (
echo "%find_%" not found at path or in the current folder
goto :EOF)
::
if not "%~1"=="" goto _calculate
echo Usage: %~0 Expression
goto :EOF
::
:_calculate
gawk 'BEGIN{printf"%%s\n",%*}'
endlocal & goto :EOF
or much more fully:
@echo off & setlocal enableextensions
::
if "%~1"=="" (call :ProgramTitle & call :ProgramHelp & goto _out)
if "%~1"=="?" (call :ProgramTitle & call :ProgramHelp & goto _out)
if "%~1"=="/?" (call :ProgramTitle & call :ProgramHelp & goto _out)
::
set gawk_=GAWK.EXE
set unxgawk_=UNXGAWK.EXE
set found1_=
for %%f in ("%gawk_%") do set found1_="%%~$PATH:f"
if exist "%gawk_%" set found1_="%gawk_%"
set found2_=
for %%f in ("%unxgawk_%") do set found2_="%%~$PATH:f"
if exist "%unxgawk_%" set found2_="%unxgawk_%"
if [%found1_%]==[""] if [%found2_%]==[""] (
call :ProgramTitle
echo Neither %gawk_% nor %unxgawk_% found at path or in the current folder
goto _out)
::
:: Keep whichever of the two that corresponds your Gawk's syntax
"%gawk_%" 'BEGIN{srand();pi=3.14159265358979;printf"%%.15g\n",%*}'
"%unxgawk_%" "BEGIN{srand();pi=3.14159265358979;printf\"%%.15g\n\",%*}"
goto _out
::
:ProgramTitle
echo +-----------------------------------------------------+
echo ^¦ GA.CMD Use gawk and unxgawk to perform calculations ^¦
echo ^¦ By Prof. Timo Salmi. Last modified Wed 26-Jan-2011 ^¦
echo +-----------------------------------------------------+
echo.
goto :EOF
::
:ProgramHelp
echo Usage: GA Expression
echo Examples: Result
echo GA 4 / 7 * 2.5 1.42857142857143
echo GA sqrt(2) 1.4142135623731
echo GA 2**4 16
echo GA exp(4*log(2)) 16
echo GA 103 %% 10 3
echo GA exp(1) 2.71828182845905
echo GA log(10) 2.30258509299405
echo GA sin(45*pi/180) 0.707106781186547
echo GA rand() 0.582076438973693 (e.g.)
echo GA int((50-10+1)*rand()+10) [A random integer 10...50]
echo GA strtonum(0xFE) 254 (unxgawk only)
echo GA strtonum(0376) 254 (unxgawk only)
echo Further options on the command line:
echo Dec to Hex: unxgawk "BEGIN{printf\"%%X\n\",254}"
echo Dec to Oct: unxgawk "BEGIN{printf\"%%o\n\",254}"
echo Date: unxgawk "BEGIN{printf\"%%s\n\",strftime(\"%%Y%%m%%d %%H%%M%%S\",systime())}"
goto :EOF
::
:_out
if not defined cmdbox if defined PauseIfFromDesktop pause
endlocal & goto :EOF
A third option is using a third-party program such as FN.EXE from
tsfunc17.zip
(or whatever is the current version number). An example
D:\TEST>fn sin(45*3.1415926536/180) /b
0.7071067812
A fourth option is using QBASIC or GWBASIC, if available. For more
see
FU.BAT Poor man's function evaluator
and the MS-DOS+Win../95/98/ME FAQ
tsbat.zip
item "141. Can I calculate factorials in a batch? Do I need
recursion?" which is sufficiently compatible with NT/2000/XP.
A fifth option is letting the CMD.EXE script build a Visual Basic
Script (VBScript)
@echo off & setlocal enableextensions
::
:: Usage
set help_=
if "%~1"=="" set help_=true
if "%~1"=="?" set help_=true
if "%~1"=="/?" set help_=true
if defined help_ (
echo.+---------------------------------------------------+
echo ^| CA.CMD Perform Visual Basic calculations ^|
echo ^| in the XP command line window ^|
echo ^| By Prof. Timo Salmi, Last modified Tue 3-Jun-2008 ^|
echo +---------------------------------------------------+
echo.
echo Usage: %~f0 Expression
echo.
echo. Result
echo Examples: CA 4 / 7 * 2.5 1.42857142857143
echo CA Round^(Sqr^(2^),3^) 1.414
echo CA 2^^^^4 16 [Note the need of double carets ^^]
echo CA 103 Mod 10 3
echo CA 103 \ 10 10
echo CA Exp^(1^) 2.71828182845905
echo CA Log^(10^) 2.30258509299405
echo CA Sin^(45*Pi/180^) 0.707106781186547
echo CA CDbl^(Rnd^) 0.575344264507294
echo CA Int^(^(50-10+1^)*Rnd+10^) [A random integer 10...50]
echo CA Hex^(254^) FE
echo CA Oct^(254^) 376
echo CA 20/4=5 -1 ^(i.e. true^)
echo CA Date-1 Date yesterday
if not defined cmdbox if defined PauseIfFromDesktop pause
goto :EOF)
::
:: File paths
set temp_=%temp%
if defined mytemp set temp_=%mytemp%
if not exist "%temp_%\" (
echo Working folder %temp_% not found
echo You may have to recreate it
goto :EOF
)
set vbscalc_=%temp_%\vbscalc.vbs
set result_=%temp_%\result.txt
::
:: Build a Visual Basic Script
echo Randomize>"%vbscalc_%"
echo Const pi=3.14159265358979>>"%vbscalc_%"
echo WScript.Echo Eval("%*")>>"%vbscalc_%"
::
:: Run it with Microsoft Windows Script Host Version 5.6
cscript //nologo "%vbscalc_%">"%result_%"
::
:: The result from the optional output file
type "%result_%"
::
for %%f in ("%vbscalc_%" "%result_%") do (
if exist %%f del %%f)
endlocal & goto :EOF
The other input/output options include e.g.
C:\_D\TEST>CA Year(Now)
2008
C:\_D\TEST>CA Month(Now)
6
C:\_D\TEST>CA Day(Now)
30
C:\_D\TEST>CA Weekay(Now)
2 (
Stands for Monday)
C:\_D\TEST>CA WeekDayName(Weekday(Now), True)
Mon (
The True stands for abbreviate)
C:\_D\TEST>CA Chr(60)
<
C:\_D\TEST>CA Asc("a")
C:\_M\TEMP\vbscalc.vbs(3, 25) Microsoft VBScript compilation error: Expected ')'
As you can observe the case of trying to return the ANSI character
code corresponding to the first letter in a string produces an error.
However, we can easily write a simple special solution to get the
codes:
@echo off & setlocal enableextensions
>"%temp%\tmp$$$.vbs" echo WScript.Echo Asc("%~1")
cscript //nologo "%temp%\tmp$$$.vbs"
for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
endlocal & goto :EOF
The output could be e.g.
C:\_D\TEST>CMDFAQ.CMD a
97
or
C:\_D\TEST>CMDFAQ.CMD ^<
60