I am trying to create a program that has the user input 3 values which the program then proceeds and uses as the A, B and C respectively in the ax^2+bx+c (discriminant = D) and gives you the "solutions" it has (if D>0 then 2 solutions, if D = 0 one "double" solution and if D < 0 it will display that there are no real solutions).
#echo off
setlocal enabledelayedexpansion
:arxh
cls
echo *****************************************
echo *Theleis na trekseis to programma (Y/N)?*
echo *****************************************
set /p V=
if /I %V%==Y goto start
if /I %V%==N goto end
echo ~~~~~~~~~~~~~~~~~~~~~~~~~
echo ~Kane thn swsth epilogh!~
echo ~~~~~~~~~~~~~~~~~~~~~~~~~
pause
goto arxh
:start
echo --------------------
echo Dwse mou thn timh A:
echo --------------------
set /p A=
echo --------------------
echo Dwse mou thn timh B:
echo --------------------
set /p B=
echo --------------------
echo Dwse mou thn timh C:
echo --------------------
set /p C=
goto calculation
:calculation
set /a D=%B%*%B%-4*%A%*%C%
echo **************************************************************************
echo ----------------------
echo Timh diakrinousas: %D%
echo ----------------------
if %D% LSS 0 goto error
if %D% GTR 0 goto positive
if %D%==0 goto zero
:error
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo ~Arnhtikh timh diakrinousas! Den uparxoun pragmatikes luseis!~
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pause
goto arxh
:positive
setlocal enabledelayedexpansion
set count=0
set /p dend=Vale edw thn timh ths diakrinousas:
set num=%dend%
for /l %%i in (%dend%, -1, 1) do (
set /a sqr=%%i*%%i
if !sqr! leq %dend% (
set digit=%%i.
set root=%%i
goto out
)
)
:out
call set /a count+=1
if %count% GTR 5 goto next
set /a dend=(%dend%-%sqr%)*100
set /a div=%root%*2
for /l %%i in (9,-1,0) do (
set /a sqr=%div%%%i*%%i
if !sqr! leq %dend% (
set root=%root%%%i
goto out
)
)
:next
set root=%root:~-5%
if %dend% neq 0 set digit=%digit%%root%
goto results
:results
set /p S=%digit%
set /a Q=(-%B%+%S%)/2*%A%
set /a R=(-%B%-%S%)/2*%A%
echo ----------------------------------------------------
echo H prwth riza einai ~%Q%~ kai h deuterh einai ~%R%~ !
echo ----------------------------------------------------
echo *****************Approximate Value*******************
pause
goto arxh
:zero
set /a Z=-b/2*A
echo -------------------------
echo H diplh riza einai: %Z% !
echo -------------------------
pause
goto arxh
:end
end
I found a program that the user inputs a number and it finds the square root of said number! I converted the code, so that the user would not input that number, but instead the number would be the discriminant (the number A,B and C would make in the equation).
No matter how hard i try, I get missing operants errors or unbalanced parenthesis or it displays to me the root of the discriminant but doesn't proceed to use it correctly in the equations below. Seriously I am stuck.
Some help would be appreciated!
P.S. don't run the code snippet, I am new here, so I used that tool to display the code.
Thank you in any case
Related
This must be very basic but i can't seem to find a way to get this done
my batch script goes like this:
#echo off
echo Type In Desired Volume And Press Enter
echo.
echo 0 = 0 %%
echo 1 = 100 %%
echo 0.10 = 10 %%
echo 0.65 = 65 %%
echo.
set /p input=
echo %input% > "C:\SetVol\Source\Volume.txt
I want to make it more user friendly by letting the user input a number between 0 and 100 instead of, for example, 0.10 for 10% audio volume. But i still need to output the 0.10 to a textfile if the user enters 10.
Google appears to longer be my best friend and we cant seem to communicate on this.
If anybody could help me get starter that would be great.
A simple way is to convert the input number to the requested output format.
One step is to prefix the input with 0.
set /p input=[Enter volume in %%]:
set "output=0.%input%"
echo %input% > "C:\SetVol\Source\Volume.txt
But this would fails for one digit values like 2%, becomes 0.2 instead of 0.02.
This can be fixed with prefix each number with 00 and take the last three digits and add a dot between.
set /p input=[Enter volume in %%]:
set "temp=00%input%"
set "output=%temp:~-3,1%.%temp:~-2%"
echo %output% > "C:\SetVol\Source\Volume.txt
You can use choice in a loop to make a key based 'slider', and then modifiy the variable value to include a 0. prefix or be 1 using an if condition:
#Echo off
set "volume=50"
:Volume
cls
Echo( Current volume: %Volume%%% [I]ncrease [D]ecrease [C]ontinue
For /f "delims=" %%G in ('Choice /N /C:IDC')Do (
If "%%G"=="I" If not %Volume% GEQ 100 Set /A Volume+=1
If "%%G"=="D" If not %Volume% LEQ 0 Set /A Volume-=1
If not "%%G"=="C" Goto :Volume
)
IF %volume% Equ 100 ( Set "Volume=1" )Else If %volume% LSS 10 (
Set "Volume=0.0%Volume%"
) Else Set "Volume=0.%Volume%"
:#your script here
For NTFS systems, a variant that stores the last set volume in an alternate data stream and reasigns the last value on return:
#Echo off
set "volume=50"
For /f "Usebackq delims=" %%G in ("%~f0:Volume")Do Set "%%G"
:Volume
cls
Echo( Current volume: %Volume%%% [I]ncrease [D]ecrease [C]ontinue
For /f "delims=" %%G in ('Choice /N /C:IDC')Do (
If "%%G"=="I" If not %Volume% GEQ 100 Set /A Volume+=1
If "%%G"=="D" If not %Volume% LEQ 0 Set /A Volume-=1
If not "%%G"=="C" Goto :Volume
)
Set Volume >"%~f0:Volume"
IF %volume% Equ 100 ( Set "Volume=1" )Else If %volume% LSS 10 (
Set "Volume=0.0%Volume%"
) Else Set "Volume=0.%Volume%"
:#your script here
Note: by using this method of input, invalid input cannot be entered.
Figured out a way to use the choice input, if anyone has a more neat or different way to do this please let me know... 291 more lines to edit...
#echo off
echo Choose Audio Volume 0-100 %%
:choice
set /P c=
if /I "%c%" EQU "0" goto :0
if /I "%c%" EQU "1" goto :1
if /I "%c%" EQU "2" goto :2
goto :choice
:0
echo 0 > C:\users\%username%\desktop\numbertest.txt
echo You chose %c% %%
pause
exit
:1
echo 0.01 > C:\users\%username%\desktop\numbertest.txt
echo You chose %c% %%
pause
exit
:2
echo 0.02 > C:\users\%username%\desktop\numbertest.txt
echo You chose %c% %%
pause
exit
I just want to ask, where is problem in this script. Every time i try to open mns fight, it just crashes somewhere on if %lokace%==2 if %vyber2%==mns set lokace=3 set monstrum=1
(btw, it's Czech game, so just ignore names)
Whole code:
:hra
cls
if %lokace%==0 echo Vesnice-domov
if %lokace%==1 echo Vesnice-namesti
if %lokace%==2 echo DabluvLes
if %lokace%==3 goto boj
echo mas %zivoty% hp
echo -----------------------------------
echo Co chces udelat?
if %lokace%==0 echo Jit na namesti [1]
if %lokace%==1 echo Jit domu [0]
if %lokace%==1 echo Jit do lesa [2]
if %lokace%==2 echo Najit monstrum [mns]
if %lokace%==2 echo Jit do vesnice [1]
if %lokace%==0 echo Vyspat se [spt]
set /p vyber2=Vyber si:
if %lokace%==1 if %vyber2%==0 set lokace=0
if %lokace%==0 if %vyber2%==1 set lokace=1
if %lokace%==1 if %vyber2%==2 set lokace=2
if %lokace%==0 if %vyber2%==spt if %zivoty% LSS %maxzivoty% set /a zivoty=%zivoty%+1
if %lokace%==2 if %vyber2%==mns set lokace=3 set monstrum=1
if %lokace%==2 if %vyber2%==1 set lokace=1
goto hra
:boj
if %monstrum%==1 set monstrumdmg=1 set monstrumhp=10
if %monstrumhp%==0 set lokace=2 set monstrum=0 goto hra
if %zivoty%==0 set lokace=0 goto hra
if %monstrumhp% GTR 0 if %monstrum%==1 echo Pavouk
echo Monstrum ma %monstrumhp% hp
echo Mas %zivoty% hp
echo Boj. Mas utok %damage% [boj]
echo Utek [utk]
set /p fight=Vyber si:
if %fight%==boj if %monstrum%==1 set /a monstrumhp=%monstrumhp%-%damage% set /a zivoty=%zivoty%-%monstrumdmg%
if %fight%==utk set lokace=2 set monstrum=0 goto hra
goto boj
set lokace=3 set monstrum=1
should be
set lokace=3&set monstrum=1
otherwise, lokace is set to 3 set monstrum=1
(there seems to be a number of such errors in the code)
Your problem: set lokace=3 set monstrum=1 sets one variable named lokace with the value 3 set monstrum=1
Possible solutions:
a) concatenate commands with a &:
set lokace=3&set monstrum=1
(a better (safer) syntay (to avoid stray spaces) would be set "lokace=3" & set "monstrum=1")
b) use code blocks:
if %lokace%==2 if %vyber2%==mns (
set "lokace=3"
set "monstrum=1"
)
c) set /a can set several variables at the same time (pure set can't), but all values have to be integers:
if %lokace%==2 if %vyber2%==mns set /a lokace=3, monstrum=1
Same problem with for example set lokace=0 goto hra
Speaking about safety: you should enclose both sides of an if comparison in quotes to avoid syntax error with empty/undefined variables:
if "%lokace%"=="2" if "%vyber2%"=="mns" ...
Example for study:
:hra
ClS
If "%lokace%"=="3" GoTo boj
If "%lokace%"=="0" Echo Vesnice-domov
If "%lokace%"=="1" Echo Vesnice-namesti
If "%lokace%"=="2" Echo DabluvLes
Echo mas %zivoty% hp
Echo -----------------------------------
Echo Co chces udelat?
If "%lokace%"=="0" (Echo Jit na namesti [1]& Echo Vyspat se [spt])
If "%lokace%"=="1" (Echo Jit domu [0]& Echo Jit do lesa [2])
If "%lokace%"=="2" (Echo Najit monstrum [mns]& Echo Jit do vesnice [1])
Set /P "vyber2=Vyber si: "
If "%lokace%%vyber2%"=="10" Set "lokace=0"
If "%lokace%%vyber2%"=="01" Set "lokace=1"
If "%lokace%%vyber2%"=="12" Set "lokace=2"
If /I "%lokace%%vyber2%"=="0spt" If %zivoty% Lss %maxzivoty% Set /A zivoty+=1
If /I "%lokace%%vyber2%"=="2mns" Set /A lokace=3,monstrum=1
If "%lokace%%vyber2%"=="21" Set "lokace=1"
GoTo hra
:boj
If "%monstrum%"=="1" Set /A monstrumdmg=1,monstrumhp=10
If "%monstrumhp%"=="0" (Set /A lokace=2,monstrum=0 & GoTo hra)
If "%zivoty%"=="0" (Set "lokace=0" & GoTo hra)
If %monstrumhp% Gtr 0 If "%monstrum%"=="1" Echo Pavouk
Echo Monstrum ma %monstrumhp% hp
Echo Mas %zivoty% hp
Echo Boj. Mas utok %damage% [boj]
Echo Utek [utk]
Set /P "fight=Vyber si: "
If /I "%fight%%monstrum%"=="boj1" Set /A monstrumhp-=damage,zivoty-=monstrumdmg
If /I "%fight%"=="utk" (Set /A lokace=2,monstrum=0 & GoTo hra)
GoTo boj
I have been having troubles with batch-codes that I would expect to work, but don't...
Below is what I have written...
#echo off
cls
:loop
set /p "input=Input a number: "
set /a "number=%input%" 2>nul
REM check if input valid
if "%input%" NEQ "%number%" (
cls
Echo Please Enter a valid number! &Echo.&Echo.
goto :loop
)
Set /a Even=number%%2
if %Even% EQU 0 (
Echo Substituting Even Number in: x / 2
Echo set /p"=(%number%) / 2 = "
set /a answer=number/2
) Else (
Echo Substituting Odd Number in: 3x - 1
<nul set /p"=3(%number%)-1 = "
set /a answer=number*3
set /a answer=answer-1
)
Echo %answer%
Echo.
Echo.
goto :loop
Echo Unexpected Error . . .
pause
Exit
Whenever I input a number into the console, it does the math, like I want it to, but prints the number -1, and every time i input another number, the number goes to -2, -3, -4, so on.
Put a setlocal enableextensions at the beginning after the #echo off, e.g.
#echo off
setlocal enableextensions
cls
Also, I think you would also need to use delayed variable expansion (usually denoted by !var!), which would change your script above to something like this:
#echo off
setlocal enableextensions enabledelayedexpansion
cls
:loop
set /p "input=Input a number: "
set /a number=!input! 2>nul
REM check if input valid
if "!input!" NEQ "!number!" (
cls
Echo Please Enter a valid number!
Echo.
Echo.
goto :loop
)
REM Make sure that it is an integer put in (just in case)
set /a int=!number! %% 1
if "!input!" NEQ "!int!" (
cls
Echo Please Enter a valid number!
Echo.
Echo.
goto :loop
)
Set /a Even=!number! %% 2
if !Even! EQU 0 (
Echo Substituting Even Number in: x / 2
set /a answer=!number! / 2
) Else (
Echo Substituting Odd Number in: 3x - 1
set /a answer=!number! * 3 - 1
)
Echo !answer!
Echo.
Echo.
goto :loop
I also would like to point out that I also fixed a few other bugs (set /p isn't of any use in this script at all, especially in where it is used, and also you need the modulus to find even/odd).
I wonder if there is a simple way to branch execution in a Windows batch file depending on the value of one single expression. Something akin to switch/case blocks in C, C++, C#, Java, JavaScript, PHP, and other real programming languages.
My only workaround is a plain if/else block where the same expression is repeatedly checked for equality against different values:
IF "%ID%"=="0" (
REM do something
) ELSE IF "%ID%"=="1" (
REM do something else
) ELSE IF "%ID%"=="2" (
REM do another thing
) ELSE (
REM default case...
)
So dumb. Is there a better solution?
I ended up using label names containing the values for the case expressions as suggested by AjV Jsy. Anyway, I use CALL instead of GOTO to jump into the correct case block and GOTO :EOF to jump back. The following sample code is a complete batch script illustrating the idea.
#ECHO OFF
SET /P COLOR="Choose a background color (type red, blue or black): "
2>NUL CALL :CASE_%COLOR% # jump to :CASE_red, :CASE_blue, etc.
IF ERRORLEVEL 1 CALL :DEFAULT_CASE # If label doesn't exist
ECHO Done.
EXIT /B
:CASE_red
COLOR CF
GOTO END_CASE
:CASE_blue
COLOR 9F
GOTO END_CASE
:CASE_black
COLOR 0F
GOTO END_CASE
:DEFAULT_CASE
ECHO Unknown color "%COLOR%"
GOTO END_CASE
:END_CASE
VER > NUL # reset ERRORLEVEL
GOTO :EOF # return from CALL
This is simpler to read:
IF "%ID%"=="0" REM do something
IF "%ID%"=="1" REM do something else
IF "%ID%"=="2" REM do another thing
IF %ID% GTR 2 REM default case...
Compact form for short commands (no 'echo'):
IF "%ID%"=="0" ( ... & ... & ... ) ELSE ^
IF "%ID%"=="1" ( ... ) ELSE ^
IF "%ID%"=="2" ( ... ) ELSE ^
REM default case...
After ^ must be an immediate line end, no spaces.
I guess all other options would be more cryptic. For those who like readable and non-cryptic code:
IF "%ID%"=="0" (
REM do something
) ELSE IF "%ID%"=="1" (
REM do something else
) ELSE IF "%ID%"=="2" (
REM do another thing
) ELSE (
REM default case...
)
It's like an anecdote:
Magician: Put the egg under the hat, do the magic passes ... Remove the hat and ... get the same egg but in the side view ...
The IF ELSE solution isn't that bad. It's almost as good as python's if elif else. More cryptic 'eggs' can be found here.
I searched switch / case in batch files today and stumbled upon this. I used this solution and extended it with a goto exit.
IF "%1"=="red" echo "one selected" & goto exit
IF "%1"=="two" echo "two selected" & goto exit
...
echo "Options: [one | two | ...]
:exit
Which brings in the default state (echo line) and no extra if's when the choice is found.
Hariprasad didupe suggested a solution provided by Batchography, but it could be improved a bit. Unlike with other cases getting into default case will set ERRORLEVEL to 1 and, if that is not desired, you should manually set ERRORLEVEL to 0:
goto :switch-case-N-%N% 2>nul || (
rem Default case
rem Manually set ERRORLEVEL to 0
type nul>nul
echo Something else
)
...
The readability could be improved for the price of a call overhead:
call:Switch SwitchLabel %N% || (
:SwitchLabel-1
echo One
goto:EOF
:SwitchLabel-2
echo Two
goto:EOF
:SwitchLabel-3
echo Three
goto:EOF
:SwitchLabel-
echo Default case
)
:Switch
goto:%1-%2 2>nul || (
type nul>nul
goto:%1-
)
exit /b
Few things to note:
As stated before, this has a call overhead;
Default case is required. If no action is needed put rem inside to
avoid parenthesis error;
All cases except the default one are executed in the sub-context. If
you want to exit parent context (usually script) you may use this;
Default case is executed in a parent context, so it cannot be
combined with other cases (as reaching goto:EOF will exit parent
context). This could be circumvented by replacing goto:%1- in
subroutine with call:%1- for the price of additional call overhead;
Subroutine takes label prefix (sans hyphen) and control variable. Without label
prefix switch will look for labels with :- prefix (which are valid) and
not passing a control variable will lead to default case.
Try by this way. To perform some list of operations like
Switch case has been used.
Checking the conditional statements.
Invoking the function with more than two arguments.
#echo off
:Start2
cls
goto Start
:Start
echo --------------------------------------
echo Welcome to the Shortcut tool
echo --------------------------------------
echo Choose from the list given below:
echo [1] 2017
echo [2] 2018
echo [3] Task
set /a one=1
set /a two=2
set /a three=3
set /a four=4
set input=
set /p input= Enter your choice:
if %input% equ %one% goto Z if NOT goto Start2
if %input% equ %two% goto X if NOT goto Start2
if %input% equ %three% goto C if NOT goto Start2
if %input% geq %four% goto N
:Z
cls
echo You have selected year : 2017
set year=2017
echo %year%
call:branches year
pause
exit
:X
cls
echo You have selected year : 2018
set year=2018
echo %year%
call:branches year
pause
exit
:C
cls
echo You have selected Task
call:Task
pause
exit
:N
cls
echo Invalid Selection! Try again
pause
goto :start2
:branches
cls
echo Choose from the list of Branches given below:
echo [1] January
echo [2] Feburary
echo [3] March
SETLOCAL
set /a "Number1=%~1"
set input=
set /p input= Enter your choice:
set /a b=0
set /a bd=3
set /a bdd=4
if %input% equ %b% goto N
if %input% leq %bd% call:Z1 Number1,input if NOT goto Start2
if %input% geq %bdd% goto N
:Z1
cls
SETLOCAL
set /a "Number1=%~1"
echo year = %Number1%
set /a "Number2=%~2"
echo branch = %Number2%
call:operation Number1,Number2
pause
GOTO :EOF
:operation
cls
echo Choose from the list of Operation given below:
echo [1] UB
echo [3] B
echo [4] C
echo [5] l
echo [6] R
echo [7] JT
echo [8] CT
echo [9] JT
SETLOCAL
set /a "year=%~1"
echo Your have selected year = %year%
set /a "month=%~2"
echo You have selected Branch = %month%
set operation=
set /p operation= Enter your choice:
set /a b=0
set /a bd=9
set /a bdd=10
if %input% equ %b% goto N
if %operation% leq %bd% goto :switch-case-N-%operation% if NOT goto Start2
if %input% geq %bdd% goto N
:switch-case-N-1
echo Januray
echo %year%,%month%,%operation%
goto :switch-case-end
:switch-case-N-2
echo Feburary
echo %year%,%month%,%operation%
goto :switch-case-end
:switch-case-N-3
echo march
echo %year%,%month%,%operation%
goto :switch-case-end
:switch-case-end
echo Task Completed
pause
exit
goto :start2
:Task
cls
echo Choose from the list of Operation given below:
echo [1] UB
echo [3] B
echo [4] C
echo [5] l
echo [6] R
echo [7] JT
echo [8] CT
echo [9] JT
SETLOCAL
set operation=
set /p operation= Enter your choice:
set /a b=0
set /a bd=9
set /a bdd=10
if %input% equ %b% goto N
if %operation% leq %bd% goto :switch-case-N-%operation% if NOT goto Start2
if %input% geq %bdd% goto N
:switch-case-N-1
echo Januray
echo %operation%
goto :switch-case-end
:switch-case-N-2
echo Feburary
echo %year%,%month%,%operation%
goto :switch-case-end
:switch-case-N-3
echo march
echo %year%,%month%,%operation%
goto :switch-case-end
:switch-case-end
echo Task Completed
pause
exit
goto :start2
If if is not working you use:
:switch case %n%=1
statements;
goto :switch case end
etc..
http://lallouslab.net/2016/12/21/batchography-switch-case/
It might be a bit late, but this does it:
set "case1=operation1"
set "case2=operation2"
set "case3=operation3"
setlocal EnableDelayedExpansion
!%switch%!
endlocal
%switch% gets replaced before line execution. Serious downsides:
You override the case variables
It needs DelayedExpansion
Might eventually be usefull in some cases.
I've been working on a little project using batch files and I've ran into a problem. As far as I'm aware there's no way to run a check to see if a certain variable is a prime number, if I'm wrong would anyone please inform me of how to do so, otherwise, can anyone think of a workaround I could use (like checking if a number is equal to a number on a list of prime numbers on a txt file or whatever).
Thanks ^^
(Also it's worth noting I'm not very knowledgeable with batch files so please excuse any idiocy I may present..)
If you have a text file of prime numbers, 1 per line (obviously up through some limit), then the solution is trivial - just use FINDSTR.
Assuming you have a NUMBER variable containing a number, then
>nul findstr /x %NUMBER% "primes.txt" && (
REM prime actions go here
echo %NUMBER% is prime
) || (
REM not prime actions go here
echo %NUMBER% is NOT prime
)
UPDATE
Here is a native batch script that can test any valid integer supported by batch (signed 32 bit ints) to see if it is prime. Performance is much better than I thought possible.
::testPrime Number
::
:: Computes whether Number is a prime or not.
:: The result is printed to stdout.
::
:: ERRORLEVEL is also set to indicate the result:
:: 0 = Prime
:: 1 = Not Prime
:: 2 = Error
::
:: Number = Any valid integral expression supported by SET /A
::
#echo off
if "%~1"=="test" (
setlocal enableDelayedExpansion
for /l %%N in (3 2 0x7fffffff) do (
set /a "test1=num %% %%N, test2=%%N*%%N"
if !test1! equ 0 exit 1
if !test2! gtr !num! exit 0
)
)
setlocal disableDelayedExpansion
2>nul set /a "num=%~1" || (
>&2 echo invalid number: %1
exit /b 2
)
if %num% leq 1 (
echo %num% is NOT prime
exit /b 1
)
if %num% leq 3 (
echo %num% is prime
exit /b 0
)
2>nul set /a "1/(num %% 2)" || (
echo %num% is NOT prime
exit /b 1
)
(
cmd /c "%~f0" test
) && (
echo %num% is prime
exit /b 0
) || (
echo %num% is NOT prime
exit /b 1
)
exit /b
The test is actually split into 2 parts, the 2nd of which is actually run in a new CMD instance. The 2nd part actually appears at the top of the script. This is done for performance reasons. It is the only way I can break out of a FOR /L loop immediately without terminating the batch script.
You can integrate your code with the script easily enough. For example:
#echo off
::----------------------------------------------------
:: This 2nd part of :testPrime must be at top of script
::
if "%~1"=="test" (
setlocal enableDelayedExpansion
for /l %%N in (3 2 0x7fffffff) do (
set /a "test1=num %% %%N, test2=%%N*%%N"
if !test1! equ 0 exit 1
if !test2! gtr !num! exit 0
)
)
:: End of 2nd part of :testPrime
::-----------------------------------------------------
:: Your code goes here
:: I'll just call the test with some representative values
::
setlocal disableDelayedExpansion
for %%N in (
1 2 3 4 100001 100003 5000009 5000011 0x7fffffff-2 0x7fffffff
) do >nul call :testPrime %%N && (
rem prime number actions go here
echo %%N is prime!
) || (
rem non-prime number actions go here
echo Not prime (%%N^)
)
exit /b
::----------------------------------------------------
:: Here is the 1st part of :testPrime
::
:testPrime
2>nul set /a "num=%~1" || (
>&2 echo invalid number: %1
exit /b 2
)
if %num% leq 1 (
echo %num% is NOT prime
exit /b 1
)
if %num% leq 3 (
echo %num% is prime
exit /b 0
)
2>nul set /a "1/(num %% 2)" || (
echo %num% is NOT prime
exit /b 1
)
(
cmd /c "%~f0" test
) && (
echo %num% is prime
exit /b 0
) || (
echo %num% is NOT prime
exit /b 1
)
exit /b
The output for the above looks like this:
Not prime (1)
2 is prime!
3 is prime!
Not prime (4)
Not prime (100001)
100003 is prime!
Not prime (5000009)
5000011 is prime!
Not prime (0x7fffffff-2)
0x7fffffff is prime!
Finally, just for yucks, I wrote a variation that lists the next prime >= or <= a given number.
::nextPrime [/less] Num
::
:: List the minimum prime number >= Num
::
:: The /L option lists the maximum prime number <= Num
::
:: The ERRORLEVEL is set to the found prime number
::
:: Num = Any valid integral expression supported by SET /A
::
#echo off
setlocal enableDelayedExpansion
if "%~1"=="test" (
for /l %%N in (3 2 0x7fffffff) do (
set /a "test1=%2 %% %%N, test2=%%N*%%N"
if !test1! equ 0 exit 1
if !test2! gtr %2 exit 0
)
)
if "%~1"=="prev" (
if !num! lss 2 exit 0
set /a "test=num%%2"
if !test! equ 0 set /a num-=1
for /l %%N in (!num! -2 2) do cmd /c "%~f0" test %%N && exit %%N
exit 0
)
if "%~1"=="next" (
if !num! lss 2 exit 2
set /a "test=!num!%%2"
if !test! equ 0 set /a num+=1
for /l %%N in (!num! 2 0x7fffffff) do cmd /c "%~f0" test %%N && exit %%N
exit 0
)
set "cmd=next"
if /i "%~1" equ "/L" (
set "cmd=prev"
shift /1
)
2>nul set /a "num=%~1" || exit /b 0
cmd /c "%~f0" %cmd% || echo !errorlevel!
And here is a demonstration of usage with output:
D:\test>nextPrime 10000000
10000019
D:\test>nextPrime /l 10000000
9999991
All of those scripts seem awfully (and unnecessarily) large to me.
An easier way to do this is using... I believe the term I'm looking for is either modulo or modulus expressions (I think modulo is the plural or modulus).
#echo off & setlocal enabledelayedexpansion
:a
cls
set /p num=Type a number to be checked:
cls
set num2=%num%-1
if %num% leq 2 goto yes
for /l %%i in (2,1,%num2%) do (
set rem=%num% %% %%i
if %rem% neq 0 goto no
)
:yes
echo %num% is a prime number.
pause
goto a
:no
echo %num% is not a prime number.
pause
goto a
Basically, it gets a user-defined variable and checks, when divided by a number, if the remainder (rem) is 0 or not.
This way is a little slow, but the shortest code. You can make it a bit shorter by putting another if statement before the for loop that checks if the number has a remainder when divided by two.
Hope it helps.
Another prime lister, this one does'nt use a file and can reach 64,000,000 if you have patience. Keeps a list of prime divisors in an environment variable. If i had a batch integer square root routine i could make it faster.
#echo off
::batch prime list up to 64M by Antoni Gual
:: does not use files!!
setlocal enabledelayedexpansion
set bitmap=
set n=Y
set /a test=3,npri=3
echo 1th prime is 2 & echo 2th prime is 3
:nextpri
set /a test+=2,index=0,div=3
if %test% LSS 8000 set bitmap=%bitmap%%n%
if %test% gtr 64000000 exit /b
:nextest
if "!bitmap:~%index%,1!"=="N" goto nextdiv
set /a resi=!test!%%!div!
if %resi% equ 0 set n=N& goto nextpri
:nextdiv
set /a index+=1, div+=2
set /a div2=div*div
if %div2% gtr %test% (
set n=Y
echo %npri%th prime is %test%
set /a npri+=1
goto nextpri)
goto nextest
The following script does not perform a primality test. Rather, it generates prime numbers up to a specific bound (the hard-coded 1000 in this particular case). You could generate the list once and then use it in your script(s):
#echo off
echo 2
echo 3
echo 2 > primenos.txt
echo 3 >> primenos.txt
set current=3
:numbercalc
set tim=3
set /a max=%current%/5
:try
set /a t=%current%/%tim%
set /a u=%t%*%tim%
if %u% EQU %current% goto noprime
set /a tim+=2
if %tim% GTR %max% goto endtry
goto try
:endtry
echo %current%
echo %current% >> primenos.txt
:noprime
set /a current+=2
if %current% GTR 1000 goto end
goto numbercalc
:end
pause
Taken from here...
Assuming you have a text file with prime numbers (each number in a single line) you could do it like this:
#echo off
if "%1"=="" (echo Syntax: %~nx0 number & exit /b 2)
for /F "tokens=*" %%p in (primes.txt) do (
if %%p EQU %1 (
echo %1 is prime!
exit /b 0
)
)
echo %1 is not prime!
exit /b 1
Example call: isprime.cmd 2 would give you 2 is prime!.
Here is what I made. It finds all prime numbers up to 214748 but it is accurate and fast and outputs the results to a file called "pn.txt" and the current number to "cn.txt" (this was to let me know what its limit was):
(#echo off)&((set n=3)&((set tn=%n%)&((set d=2)&((set d2=)&((set m=100)&((echo.prime-numbers>pn.txt)&((echo. >>pn.txt)&((echo.1>>pn.txt)&((echo.2>>pn.txt)&((echo.1)&((echo.2)&(goto a))))))))))))
:a
(echo.%n%cn.txt)&((set tn=%n%)&(set tn=%n:~-1%))
(if %tn%==2 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==4 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==6 ((set /a n=%n%+1)&((set d=2%d2%)&(gotoa))))&((if %tn%==8 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==0 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&(goto b)))))
:b
((set /a tn=%d%*%d%)&(if /i %tn% equ %n% ((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))&((if /i %tn% gtr %n% ((set tn=%n%)&((set l=%d%)&((if /i %n% equ 10000 (set d2=0))&((if /i %n% equ 100000 set (d2=00))&((set d=2%d2%)&((set m=100%d2%)&(goto d)))))))&((set /a d=%d%+1)&(goto b))
:d
(title verifing %n% at %d%)&(set tn=%n%)
set /a tn=%tn%*%m%
set /a tn=%tn%/%d%
set tn=%tn:~-2%
(if /i %tn% equ 00%d2% ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&(((set /a tn=%n%-1)&(if %d%==%tn% ((echo.%n%)&((echo.%n%>pn.txt)&(((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))))&(if %d%==%l% ((echo.%n%)&((echo.%n%>pn.txt)&((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))))&((set /a d=%d%+1)&(goto d)))
#echo off
::PRIMES
set multiple2=1
set add=1
set counter=1
color f0
set /p range=Computer primes 0-?:
set /a limit=(range/2)+1
set ut=3
mkdir prime0-%range%
cd prime0-%range%
echo >>2
:opipe
echo >>%ut%
set /a ut=ut+2
if %ut% GEQ %range% goto next
goto opipe
:next
set /a multiple2=multiple2+2
if %multiple2% GEQ %limit% goto end
set /a add=add+2
set /a multiple=multiple2
:process
set /a multiple=multiple+add
del %multiple%
if %multiple% GEQ %range% goto next
goto process
:end
CD ..
echo 2 >>ALLprime0-%range%.txt
:offx
set /a counter=counter+2
if exist prime0-%range%\%counter% echo %counter% >>ALLprime0-%range%.txt
if %counter% GEQ %range% goto down
goto offx
:down
echo Computation Succesful
pause
exit
::RMDIR /S /Q prime0-%range%
Please excuse me for beating a dead horse. Here is a radically differnt approach to generating primes in pure batch that overperforms everything else I have found .
It's based in Keeping a list of multiples of previous found primes around the window we're checking. The numbers not found in the list are primes. For keeping the list I use environment variables of the form #composite=next_increment .It uses a single loop, much faster and degrading slower than the nested double loop used in other algorithms. Unforunately a FOR and an auxiliar subrputine are required to overcome the impossiblilty of having repeated keys in environment, as sometimes multiples of different primes clash.
BTW the idea comes from an exerciste in Knuth's TAOCP Vol 3 page 617.
:: prime table using rotating multiples stored in environment
#echo off
setlocal enabledelayedexpansion
mode con cols=90
set #25=-10
set /a num=7,inc1=4,cnt=0,inc2=0,num1=0, maxprime=10000
set lin= 0:
call:line 2 & call:line 3 & call:line 5
:nextnum
if defined #%num% (
for %%i in (!#%num%!) do (
if %%i lss 0 (set /a num1=%num%-%%i,"inc2=-%%i<<1") else (set /a num1=%num%+%%i,"inc2=-(%%i>>1)")
call :aux !num1! !inc2!
)
set #%num%=
) else (
call :line %num%
set /a num1= num * num
if %inc1% equ 4 (set/a "inc2=num<<2") else (set /a "inc2=-(num<<1)")
if !num1! leq %maxprime% set #!num1!=!inc2!
)
set /a num+=inc1, inc1=6-inc1
if %num% lss %maxprime% goto nextnum
echo %lin%
pause & goto:eof
:aux
if %1 leq %maxprime% set #%1=%2 !#%1!
goto:eof
:line formats output in 10 right aligned columns
set num2= %1
set lin=%lin%%num2:~-8%
set /a cnt+=1,res1=(cnt%%10)
if %res1% neq 0 goto:eof
echo %lin%
set cnt1= %cnt%
set lin=%cnt1:~-5%:
goto:eof
#echo off
:top
set /p number=number:
set /a check=1
:work
set /a check=%check%+1
set /a result=%number%/%check%
set /a abc=%result%+1
if %abc% LSS %check% goto end
SET /a modulo=%number% %% %check%
IF %modulo%==0 (goto factor
) ELSE (goto notfactor
)
:factor
echo %check%
set /a other= %number%/%check%
echo %other%
echo.
goto work
:notfactor
goto work
:end
echo If you see 2 numbers this its a prime otherwise its composit
echo.
echo i am too lazy to code it further and have already spend way too much time trying to make this
pause
cls
goto top
this will also tell the prime factors if any.