# Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

# A high-precision pi calculator that uses entirely batch commands.

#### Joe Caverly

I found this example, which does not work with TCC, but works with CMD.
Code:
@if defined talk (echo on) else (echo off)
setlocal EnableDelayedExpansion
echo.pi.bat  -  By Don Cross  -  http://cosinekitty.com

echo.
echo.%time% - started
echo.

call :PiEngine 48 18 32 57 -20 239
call :PiEngine 16 5 -4 239
goto :EOF

:PiEngine
call :SetToInteger Pi 0
set Formula=
:PiTermLoop
if "%1" == "" (
call :Print pi
echo.
echo.!time! - finished !Formula!
echo.
goto :EOF
)
call :ArctanRecip PiTerm %2
set /a PiEngineFactor=%1
if !PiEngineFactor! lss 0 (
set /a PiEngineFactor *= -1
set Formula=!Formula!
call :MultiplyByInteger PiTerm !PiEngineFactor!
call :Subtract Pi PiTerm
set Operator=-
) else (
call :MultiplyByInteger PiTerm %1
set Operator=+
)
if defined Formula (
set Formula=!Formula! !Operator! !PiEngineFactor!*arctan^(1/%2^)
) else (
set Formula=pi = %1*arctan^(1/%2^)
)
shift
shift
goto PiTermLoop

:SetToInteger
for /L %%i in (0, 1, !MaxQuadIndex!) do (
set /a %1_%%i = 0
)
goto :EOF

:Print
set PrintBuffer=x
REM  Omit a couple of least significant quads, because they will have roundoff errors.
if defined PiDebug (
) else (
)
set PrintDigit=!%1_%%i!
if !PrintDigit! lss 1000 (
if !PrintDigit! lss 100 (
if !PrintDigit! lss 10 (
set PrintDigit=000!PrintDigit!
) else (
set PrintDigit=00!PrintDigit!
)
) else (
set PrintDigit=0!PrintDigit!
)
)
set PrintBuffer=!PrintDigit!!PrintBuffer!
)
echo.%1 = !PrintBuffer!
goto :EOF

: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

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

:ArctanRecip
if defined PiDebug echo.ArctanRecip %1 %2
call :SetToInteger %1 1
call :DivideByInteger %1 %2
call :CopyValue AR_Recip %1
set /a AR_Toggle = -1
set /a AR_K = 3
:ArctanLoop
if defined PiDebug (
echo.
echo.ArctanRecip  AR_K=!AR_K!    ---------------------------------------------------------
)
call :DivideByInteger AR_Recip %2
call :DivideByInteger AR_Recip %2
call :CopyValue AR_Term AR_Recip
call :DivideByInteger AR_Term !AR_K!
call :CopyValue AR_PrevSum %1
if !AR_Toggle! lss 0 (
call :Subtract %1 AR_Term
) else (
)
call :Compare AR_EqualFlag %1 AR_PrevSum
if !AR_EqualFlag! == true goto :EOF
set /a AR_K += 2
set /a AR_Toggle *= -1
goto ArctanLoop

:CopyValue
if defined PiDebug echo.CopyValue %1 %2
for /L %%i in (0, 1, !MaxQuadIndex!) do (
set /a %1_%%i = %2_%%i
)
goto :EOF

if defined PiDebug echo.Add %1 %2
if defined PiDebug call :Print %1
if defined PiDebug call :Print %2
for /L %%i in (0, 1, !MaxQuadIndex!) do (
set /a %1_%%i = Add_Digit %% 10000
)
goto :EOF

:Subtract
if defined PiDebug echo.Subtract %1 %2
if defined PiDebug call :Print %1
if defined PiDebug call :Print %2
set /a Subtract_Borrow = 0
for /L %%i in (0, 1, !MaxQuadIndex!) do (
set /a Subtract_Digit = %1_%%i - %2_%%i - Subtract_Borrow
if !Subtract_Digit! lss 0 (
set /a Subtract_Digit += 10000
set /a Subtract_Borrow = 1
) else (
set /a Subtract_Borrow = 0
)
set /a %1_%%i = Subtract_Digit
)
goto :EOF

:Compare
if defined PiDebug echo.Compare %1 %2 %3
if defined PiDebug call :Print %2
if defined PiDebug call :Print %3
set /a Compare_Index = 0
set %1=true
:CompareLoop
if not !%2_%Compare_Index%! == !%3_%Compare_Index%! (
if defined PiDebug echo.!%2_%Compare_Index%! neq !%3_%Compare_Index%!
set %1=false
goto :EOF
)
set /a Compare_Index += 1
if defined PiDebug echo.Compare equal
goto :EOF
)
goto CompareLoop

REM    $Log: pi.bat,v$
REM    Revision 1.2  2007/09/06 21:49:15  Don.Cross
REM    Added time stamps and display of formula.
REM
REM    Revision 1.1  2007/09/06 21:12:36  Don.Cross
REM    Batch file for calculating pi
REM
Joe

I also noticed that when I run this under TCC/Tcmd, that neither Ctrl+C nor Ctrl+Break actually stop execution of the script.

I have to hit Ctrl+Break multiple times to interrupt the script and stop it.

Under TCMD, Ctrl-C works fine. Not so under CMD, however. Strange.

Under both, the batch produces a divide-by-zero error here.

On my Windows 7 x64 system, running CMD.EXE 64-bit or CMD.EXE 32-bit, this is what I get;
Code:
c:\utils>pi.cmd
pi.bat  -  By Don Cross  -  http://cosinekitty.com

17:37:37.85 - started

pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086

17:37:41.25 - finished pi = 48*arctan(1/18) + 32*arctan(1/57) - 20*arctan(1/239)

pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086

17:37:44.75 - finished pi = 16*arctan(1/5) - 4*arctan(1/239)

TCC 18.00.32 x64 returns;
Code:
c:\users\jlc\utils>pi.cmd
pi.bat  -  By Don Cross  -  http://cosinekitty.com

17:39:58.88 - started

MAPM Warning: 'M_apm_sdivide', Divide by 0
TCC: C:\Users\jlc\utils\pi.cmd [90]  Divide by zero " DBI_Digit /"

TCC-RT 21.01.49 x64 returns;
Code:
c:\users\jlc\utils>"C:\Program Files\JPSoft\TCC_RT_21\tcc.exe" /I /Q /C pi.cmd
pi.bat  -  By Don Cross  -  http://cosinekitty.com

17:41:28.66 - started

TCC: C:\Users\jlc\utils\pi.cmd [90]  Divide by zero " DBI_Digit %"
TCC: C:\Users\jlc\utils\pi.cmd [90]  Divide by zero " DBI_Digit /"

Joe

I am impressed that the author was able to beat CMD into producing these results. And saddened that he wasted days of his life doing it.

The same result of his 195-line CMD batch file can be done in 1 line in TCC:

echo pi = %@eval[pi=0.108]

Or if you want a really high resolution pi:

echo pi=%@eval[pi=0.10000]

TCC calculating pi to 10,000 decimal places runs about 600 times faster than the CMD batch file calculating it to 108 places.

And the reason the batch file doesn't run in TCC is because of invalid syntax in his SET /A statements. Which CMD is rewriting internally to the correct format, which is (1) undocumented, and (2) inconsistent with how it parses SET statements without the /A. But I have made a change for 21.01.50 to emulate this undocumented behavior. Who knows, it might even be a CMD "feature".

[FOX] Ultimate Translator
Translate