Magic with BASIC in Batch Files |
NOTE: This page has been maintained primarily for legacy purposes. Although
GW-BASIC is the perfect engine for this function, it will not run on systems. If desired, one could adapt this method to any modern version of BASIC. |
Let us assume that you spend a lot of time at the DOS prompt.
Either your PC is old and slow, or you have a DOS-capable
hand-held device, or you prefer to perform file-maintenance
tasks in a DOS window, or — heaven forbid —
you simply love DOS. Anyone who programs in BASIC should fall into
one of these categories.
Creating your own program is great, but having to load the BASIC
Interpreter in order to execute the code might not be so great.
If all that you desire is some sort of little utility that performs a
short task, then the hassle might not be worth it. If you cannot
compile your code, or you need to limit the file sizes, then your options
are limited. Also, there is no way to supply command-line
instructions to the BASIC Interpreter. What can you do?
One solution is the batch file. It is possible to run
GW-BASIC, load and execute a program with parameters supplied
at the DOS prompt, close down BASIC, delete temporary files, and return
control to the DOS prompt — all within a fraction of a
second, and with all internal activity transparent to the user!
Moreover, it's easy — and fun.
Here is one way to accomplish the mission:
Let's try a simple example. Either you are studying probability
in school, or you play a lot of fancy keno tickets. So you have
occasion to calculate the combinations of N things,
taken R at a time. (Example: if you have
5 marbles of different colors, how many 2-color combination
are there?) The objective is to be able to enter something such
as at the DOS prompt, and have the answer
printed on the screen. Here is a workable batch file:COMBO 14 5
:COMBO.BAT (combinations of N things R at a time)
@echo off
set f=c:\temp\parm
echo %1 > %f%
echo %2 >> %f%
gwbasic c:\prgmfile\combo
del %f%
set f=
This page is not intended as a tutorial on batch-file protocols, as that information can be found on a batzillion other pages; nevertheless, I will explain briefly:
Now, let's create COMBO.BAS:
10 '---[ Combo = combinations of N things R at a time]--- 11 ' 20 OPEN "i",1,"C:\TEMP\PARM" 30 INPUT$ #1,N$: N=VAL(N$) 40 INPUT$ #1,R$: R=VAL(R$) 49 ' 50 COMBO=N 60 FOR J=2 TO R 70 COMBO=COMBO*(N+1-J)/J 80 NEXT J 89 ' 90 PRINT "Combinations:" COMBO 99 SYSTEM
Place this file in the directory indicated in the batch file,
and you are ready to test your new system. At the DOS prompt,
enter with one or more spaces
between the parameters, and almost instantaneously the text
COMBO 8 3
, is output to the screen.
Surely enough, Combinations: 56
8 items can be selected 3 at a time
in 56 unique ways. It works!
Observe, however, that the input must make sense. Should you
enter something other than integers, the result will be nonsensical.
Garbage in, garbage out. Error-trapping of input always
is desirable, and we'll do some of that in the next exercise.
This routine can easily be augmented to include calculations for Permutations and Factorials. I have done that in a file available for downloading (see end of page).
This next project is admittedly an esoteric one. If you are
comfortable with BASIC and not with batch files, then you might prefer
to stick with the method just covered. However, those interested
in batch-file programming will find this method more interesting.
The goal is to create a system that extracts the prime factors of an integer. That will be more fun than calculating combinations. However, unlike COMBO, the BASIC program will be created within the batch file itself! The procedure is somewhat more complicated, but it results in a cleaner setup in that there is no BASIC program to store. Here is our simple algorithm:
In the most efficient setup, the divisors would be the successive
primes; but that really isn't necessary for our purposes. You will find
that factoring integers up to 11 or 12 digits runs plenty
fast even with this minimal structure, and without being compiled.
The crux of our algorithm:
{ N is the number to be factored. X is set equal to N. D is the divisor. E is the exponent }
300 WHILE X>=D^2 AND X>1 310 D=D+1-(D<>2): E=0 320 IF X/D=INT(X/D) THEN X=X/D: E=E+1: GOTO 320 330 IF E THEN F$=F$+""+STR$(D) 340 IF E>1 THEN F$=F$+"^"+RIGHT$(STR$(E),LEN(STR$(E))-1) 350 WEND 399 ' 400 IF X<>N AND X<>1 THEN F$=F$+""+STR$(X) 410 IF X<>N THEN PRINT "Prime factors:" F$ 420 IF X=N THEN PRINT TAB(3); N; "is prime." 430 END
Before writing the batch file, let us establish another couple of useful protocols. Let's decide to name all temporary files as "$----"; that way, they always will be recognizable as such. Let's also plan always to put them in the directory C:\TEMP (or whatever you prefer). It also is useful to include a Help screen in the batch file, lest the user forget what the program does or how the input should be structured.
Firstly however, there are a couple of snags to overcome.
The BASIC '>' and '<' symbols cannot be used as text
within a batch file, unless they are enclosed in quotes. Also, the
crummy DOS-equivalent featured in Windows XP chokes on (that is,
ignores) the carat '^' symbol, unless it also is inside quotes.
Earlier versions of Windows didn't have this problem; eventually,
Microsoft will succeed in eliminating the Windows command-prompt
entirely, which will force us DOS lovers to set up a dual-boot
system with DOS 6.22 or Windows 98. Perhaps you already have
done that; it's easy enough.
Meanwhile, it will be necessary to code exponential functions and
certain relational expressions in other ways. An expression such
as D^2 can be written as D*D, so we will do
that (larger or fractional exponents also could be accommodated by
the use of LOG and EXP). Relational expressions can
be converted to something workable by judicious use of the
absolute-value construct.
While we're at it, let's include a little Help screen. Here is a working batch file:
:FACTORS.BAT (extracts prime factors)
@echo off
if %1!==! goto Help
set f=c:\temp\$factors.bas
echo 1 defdbl a-z: n=%1: x=n: color 14,1:
? > %f%
echo 2 while x-d*d = abs(x-d*d): e=0: if d=2
then d=3 else d=d+2 >> %f%
echo 3 if x/d = int(x/d) then x=x/d: e=e+1: goto 3
>> %f%
echo 4 if e then ? d;: if e-2 =
abs(e-2) then ? "^" E; >> %f%
echo 5 wend: ? x;: if x=n then ? "is prime." >>
%f%
echo 6 system >> %f%
gwbasic.exe %f%
del %f%
set f=
goto End
:Help
echo.
echo Usage: FACTORS positive integer (15-digit max)
echo.
:End
Explanation:
I did promise some error-trapping capability, so let us finish up by
restricting user input to as appropriate number. GW-BASIC
double-precision stores 17 digits, but will print
only 16. My testing has shown that this routine fails on
certain 16-digit numbers; so let us arbitrarily limit the size
to 15 digits. Also, negative numbers and non-integers
are unacceptable. Here is an updated program, which will catch most
errors:
:FACTORS.BAT (extracts prime factors)
@echo off
if %1!==! goto Help
set d=c:\temp\
set f=$factors.bas
echo 1 on error goto 10: if not %1-2 =
abs(%1-2) goto 10 > %f%
echo 2 if not %1 = int(%1) goto 10 >> %f%
echo 3 z=log(1E+15): if not z-log(%1) = abs(z-log(%1)) goto 10
>> %f%
echo 4 defdbl a-z: n=%1: x=n: color 14,1:
? > %f%
echo 5 while x-d*d = abs(x-d*d): e=0: if d=2 then
d=3 else d=d+2 >> %f%
echo 6 if x/d = int(x/d) then x=x/d: e=e+1: goto 6 >>
%f%
echo 7 if e then ? d;: if e-2 = abs(e-2)
then ? "^" E; >> %f%
echo 8 wend: ? x;: if x=n then ? "%1 is prime."
>> %f%
echo 9 system >> %f%
echo 10 shell "rem > %d%$err":
system >> %f%
gwbasic.exe %f%
if not exist %d%$err goto Cleanup
:Help
echo.
echo Usage: FACTORS positive integer (15-digit max)
echo.
:Cleanup
if exist %d%$*.* del %d%$*.*
set f=
set d=
Explanation:
So there you have it. At the command prompt, enter
, and up pops a listing of the
three prime components:
FACTOR 16790123457
3 ^ 2 17 ^ 3 379721
.
Try it again:
This runs somewhat slower, then produces the message:
FACTOR 16790123473
.16790123473 is prime
.
It's all a matter of total loops. The smaller the factors,
the faster the process will be completed. Should you try
it will run for a lot
longer time, because that number also is prime. Each extra digit
potentially increases the runtime by a factor FACTOR 167901234579971
,of 5.
This particular calculation requires 12 seconds on my PC,
even when compiled; but anything up to 13 digits spits out a
solution immediately.
I include two other utilities that you might find useful:
– MATH.BAT –
Do you miss the ability to actually calculate something
from the DOS prompt? Now you can. Virtually any math problem
that BASIC can understand may be entered at the DOS prompt.
For example, enter
the screen will clear, then will display both the problem and its
solution:
MATH 380 +16*LOG(27/4) -9.5
;380 +16*LOG(27/4) -9.5 = 372.4096
.
Enter MATH by
itself for a listing of all the available functions, plus a couple of
extras, such as using P=pi and R=radians. But remember the legacy
of XP; the carat (^) cannot be used. To calculate, for
example, 3^4.5, enter
The answer will be displayed: MATH EXP(LOG(3)*4.5)
.140.2961
.
– AMORT.BAT –
With this one, you simply enter an amount to finance, interest rate, and term, and it will display the monthly charge on the principal.
Download: Batches.zip All four batch files