equations in command prompt - batch-file

I am very new to batch, and I have this program that is SUPPOSED to take data in then echo the output of the data, but I need help on making a varible from an equation in cmd. Here is the code to my program. Could anybody tell me what i am doing wrong here? Thanks!
#echo off
title growth factor y varible tool
set/p yintercept=enter the y intercept
echo %yintercept%
set/p exponent=enter the exponent
echo %exponent%
set/p x=enter x value
echo %x%
cls
echo %yintercept%
echo %exponent%
echo %x%
eq = %yintercept% ( %exponent% ^ %x% )
pause >nul

Here is a working sample of your code:
#echo off
title Growth factor y varible tool
set /p yin="Enter the y intercept: "
set /p exp="Enter the exponent: "
set /p x="Enter x value: "
pause
cls
echo Y-intercept: %yin%
echo Exponent: %exp%
echo X value: %x%
echo.
set /a pow=1
for /l %%a in (1, 1, %x%) do set /a pow*=exp
set /a eq=yin*pow
echo Equation = %yin% * (%exp%^^%x%)
Echo = %yin% * %pow%
Echo = %eq%
pause >nul
If you input:
Enter the y intercept: 2
Enter the exponent: 3
Enter x value: 4
Press any key to continue . . .
It outputs:
Y-intercept: 2
Exponent: 3
X value: 4
Equation = 2 * (3^4)
= 2 * 81
= 162
And as you can see includes a bit of working. You can easily get rid of this by commenting the respective lines.

Firstly, you have not used the set command when trying to evaluate %yintercept% ( %exponent% ^ %x% ). You need to use set with the /a switch for arithmetic.
However, it looks like you are trying to evaluate %exponent% to the power of %x%. There is no operator to do this with the set command. See this question for an explanation on how to do this in Batch. Note: in CMD the set command evaluates carat symbol ^ as bitwise exclusive or, and since carat is used as an escape character, you would need to encase this expression in quotation marks, or add a second carat.
Also, The set command does not imply multiplication symbols. So you need to include * where you would like multiplication to occur.
Type set /? into a command prompt for an explanation on how to use the set command, specifically the section on the /a switch.

Related

How to add values to batch script variables?

I know this may sound dumb, but I am a beginner at batch script, so I know almost nothing about it. Anyway, I want to change a variable; add 1 to it, here is my code:
#echo off
set num = 1
set num = %num% + 1
echo %num%
#echo on
Firstly, never use spaces in a standard set before and after =. This will create a variable with a trailing space and a value with a leading space. So technically you will have %num % and 1.
To demonstrate this, simply copy everything below and paste into a cmd prompt.
#echo off
set dummy = test
set dummy
echo %dummy%
echo %dummy %
#echo on
similarly with:
#echo off
set num = 1
set num | findstr /v "NUMBER"
set /a num+=1
set num | findstr /v "NUMBER"
echo %num%
echo %num %
#echo on
will result in two variables, %num % with a value of 1 and %num% with a value of 1
The results from the above will clarify your question in the comments.
To solve your arithmetic question, simply use the /a switch to specify that the values are numerical and we can use arithmetic sequence operators etc. on it.
#echo off
set "num=1"
set /a num+=1
echo %num%

Basic BAT calculator command

I am trying to do a very basic 2 value input BAT file but I am struggling. I used a free template from Wikihow and re-adjusted but something is not right.
I want to calculate 100/(A/B+1) and I know for a fact that the Batch calculation ignores the "+1" for some reason and basically just calculates "100/(A/B). Please help. Thanks.
TITLE Calculator
ECHO OFF
CLS
:TOP
color 3f
Cls
:SUM
CLS
ECHO ---------------------------------------------------
ECHO[
ECHO Division
ECHO[
ECHO ---------------------------------------------------
ECHO[
set /p A=" Enter First Amount = "
ECHO[
set /p B=" Enter Second Amount = "
SET /A C=100/(A/B+1)
ECHO[
ECHO ---------------------------------------------------
ECHO Result %C%
PAUSE
GOTO:TOP
I suspect this is an order of operations issue.
Remember that plus comes after division.
You might need this instead:
SET /A C=100/(A/(B+1))
This will allow the B+1 to come before the division.
SET /A doesn't ignore the +1:
E.g. SET /A 100/(10/2+1) outputs 16; the problem you most likely have is this:
Any SET /A calculation that returns a fractional result will be
rounded down to the nearest whole integer.
(Source)
However, it is possible to work around this issue:
SETLOCAL EnableDelayedExpansion
SET /A "var=100000/(10/2+1)"
SET "fraction=%var:~-3%" & SET /A "var/=1000"
IF !fraction:~-1! GEQ 5 SET /A "fraction+=10"
SET "fraction=!fraction:~0,-1!"
ECHO %var%.%fraction%
Basically you multiply the number to be divided by 10^(n) and - after you set the fraction (%var:~-n%) - divide it by 10^(n) again. Then you check the last digit of the fraction for proper rounding and remove it (read more).
I am assuming you were looking for:
SET /A C=(A/B)+1
SET /A C=100/(C)
This the correct formula, but it will not return the correct results for fractioned numbers.
So if A = 10 and B = 2
10 / 2 = 5 +1 =6
100/6 = 16,6 but batch rounds off to 16.
Then A = 453 and B = 178
453 / 178 = 2,544943820224719
2,544943820224719 + 1 = 3,544943820224719 but Batch rounds off to 3
100/3 = 33
So if you use numbers that will cause fractions, you MUST use a solution that include fractions.

An If statement in my .bat script isn't working as expected

What is supposed to happen is that you input a number between 1 and 1,048,567. The program checks if your input is actually a number between 1 and 1,048,567. If your input is a valid number then it will continue onto the next bit of code. If the input is invalid then it will display a message saying it is invalid then loop back and ask you for input again.
When I run this however, I input anything and it says invalid input even if I did input a number between 1 and 1,048,567.
Code:
:setup
#echo off
title Pokemon Shiny Sim
set delay = nul
set count = 0
set chance = 4096
:settings
:setChance
cls
echo Set shiny chance (1 in x). Range: (1-1,048,567)
echo Leave blank for 1 in 4096.
set /p chance = Input:
set /a chance = %chance%+0
if %chance% GEQ 1 (
if %chance% LEQ 1048567 (
goto setDelay
)
)
echo Invalid Input.
pause
goto setChance
:setDelay
cls
echo Set delay between attempts in seconds. Range: (1-60).
echo Leave blank for no delay.
set /p delay = Input:
set /a delay = %delay%+0
if %delay% == nul (
goto loopStart
)
if %delay% GEQ 1 (
if %delay% LEQ 60 (
cls
goto loopStart
)
)
echo Invalid Input.
pause
goto settings
:loopStart
set /a count = %count%+1
set /a rand = %random% %% %chance%+1
if %rand% == 1 (
echo Attempt: %count% | Shiny: Yes!
pause
)
else (
echo Attempt: %count% | Shiny: No
)
goto loopStart
I suggest to read first debugging a batch file and second the answer onWhy is no string output with 'echo %var%' after using 'set var = text' on command line?
Next look on your rewritten code below:
:setup
#echo off
title Pokemon Shiny Sim
set "delay=0"
set "count=0"
set "chance=4096"
:settings
:setChance
cls
echo Set shiny chance (1 in x). Range: (1-1,048,567)
echo Leave blank for 1 in 4096.
set /P "chance=Input: "
set /A chance+=0
if %chance% GEQ 1 if %chance% LEQ 1048567 goto setDelay
echo Invalid input.
pause
goto setChance
:setDelay
cls
echo Set delay between attempts in seconds. Range: (1-60).
echo Leave blank for no delay.
set /P "delay=Input: "
set /A delay+=0
if %delay% == 0 goto loopStart
if %delay% GEQ 1 if %delay% LEQ 60 cls & goto loopStart
echo Invalid input.
pause
goto settings
:loopStart
set /A count+=1
set /A rand=%random% %% chance + 1
if %rand% == 1 (
echo Attempt: %count% ^| Shiny: Yes!
pause
) else (
echo Attempt: %count% ^| Shiny: No
)
goto loopStart
All spaces around the equal signs are removed in this batch code.
The command line set "delay = nul" is modified to set "delay=0" because the condition if %delay% == nul is never true after execution of set /a delay = %delay%+0 resulting in execution of set /a delay = nul + 0 which results in assigning value 0 to environment variable delay on nul not existing as environment variable with that name having an integer value. The result of a valid arithmetic expression is always a number assigned as string to the environment variable and never a string like nul.
set /a chance = %chance%+0 is modified to set /A chance+=0 and set /a delay = %delay%+0 is modified to set /A delay+=0 because otherwise the input check is insecure as the user has for example the freedom to enter | for variable chance resulting in execution of command line set /a chance = |+0 which cause an unexpected exit of batch file execution.
Never use %variable% or !variable! in an arithmetic expression as not needed in general.
The help output on several pages on running set /? in a command prompt window explains in chapter about usage of set /A that each string which can't be interpreted as number or operator isĀ interpreted automatically as name of an environment variable whose current value should be converted to an integer on evaluation of the expression. If the environment variable is not defined at all or its value can't be successfully converted to a 32-bit signed integer, it is replaced in the expression by integer value 0.
There are exceptions like the usage of a random number in an arithmetic expression which requires %random% or !random! or when a variable name contains a space character or a character which would be interpreted as operator. In such cases it is necessary that the Windows command interpreter replaces the environment variable name already in preprocessing state or immediately before execution of the command set by random value respectively value of the environment variable.
set /a chance = %chance%+0 makes it also possible that the user of this batch file enters for example PROCESSOR_LEVEL or PROCESSOR_REVISION and this input although not being a number at all would be handled as valid because those two strings are the names of environment variables having numbers as values. PROCESSOR_REVISION has by default a hexadecimal number assigned which can be processed nevertheless completely or partly as number by command set.
Another syntax error is in block
if %rand% == 1 (
echo Attempt: %count% | Shiny: Yes!
pause
)
else (
echo Attempt: %count% | Shiny: No
)
The keyword else must be on same line as the closing ) of true branch of the IF condition separated from ) with a space character.
And redirection operator | must be escaped with caret character ^ to be interpreted as literal character to output into console window.
Note: set /A chance+=0 makes it still possible to enter for example 170 percent or 170X which results in chance having value 170 and therefore input is valid although in real the entered string is not a number.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
cls /?
echo /?
goto /?
if /?
pause /?
set /?
title /?
I haven't tested the code yet, but I found some fatal issues in the code.
Mis-setting variable
set /a count = %count% + 1
This sets a variable count (Note the space!). Remove the space! Also, this can be shortened to set /a count+=1.
ECHOing special characters
| is one of the special characters reserved for redirection in batch. To properly echo it, use echo string ^| string instead.
Poor IF statement practice
if %rand% == 1 (
only works when %rand% is alphanumeric. If %rand% is space, the cmd.exe sees:
if == 1 (
which is incorrect.
To correct it, do
if "%rand%"=="1" (
Alternatively, use EQU for numeric comparison, and == for string comparison.

Batch file says ( was unexpected at this time during if

So I am making a batch file that will generate a random number, keep it in a variable, and then you try to guess it. If you guess lower than the number, it will make your try counter go up by one, and tell you to guess higher, and vice versa. However, when I enter a number, it says ( was unexpected at this time. Can anyone help me?
Here is the code:
#echo off
cls
:1
setlocal EnableDelayedExpansion
set /a x = 0
set /a x = %RANDOM:~-3%
endlocal
goto 2
:2
set /p v = Enter your guess:
if %v% lss %x% (
echo Greater than that!
set /a g = %g%+1
title %g% Guesses so far!
goto 2
) else if %v% gtr %x% (
echo Less than that!
set /a g = %g%+1
title %g% Guesses so far!
goto 2
) else if %v% equ %x% (
echo Correct! It was %x%! It also took you %g% guesses to find it!
set /a g = 0
title %g% Guesses so far!
goto 1
)
echo That's not a number!
goto 2
Batch is sensitive to spaces in a SET statement. SET FLAG = N sets a variable named "FLAGSpace" to a value of "SpaceN"
consequently, v is not set up and the if is interpreted as if lss 4 (
You will also have problems with setting a variable like g within a ode block (parenthesised sequence of lines). %g% will be evaluated at parse-time - it is not interpreted as the run-time value (ie. as code controlling the block is executed)
Pleas see many SO articles on delayed expansion my using the search facility on the top bar of the page.
Your problem is:
set /a x = 0
:: make it be:
set /a x=0
No Space.

Simple math program wont work?

I'm trying to create a batch program that will add the input to 232, then divide the result by 470. It would also be nice if someone told me how to make it so that if the user inputs a letter instead of a number, or an invalid character, anything besides a number, the program would execute a "goto command." Thanks!
PS the current code outputs 0, regardless of input.
Heres my code:
#echo off
title Grade
:1
cls
set /p input= "Grade: "
set /a input1= input + 232
set /a input2= input1 / 470
echo %input2%
pause
goto 1
For your division equation, batch files do not support floating point arithmetic, so you won't get a true answer. Anything less than 238 for input returns a 0 for your quotient.
Here's some code to let you see how to guarantee numeric input.
:Blurb
#Echo off
Cls
Echo Grade Math
:GetNum
Echo.
Set /p _Input="Grade: "
Set "_Num="
For /f "delims=0123456789" %%i in ("%_Input%") Do Set "_Num=%%i"
If Defined _Num Echo.&Echo Invalid: please enter a number.&Goto :GetNum
:DoMath
Set /a _Sum= _Input + 232
Echo Sum = %_Sum%
Set /a _Quotient= _Sum / 470
Echo Quotient = %_Quotient%
Pause
Goto :GetNum
:End

Resources