npocmaka
Just compared the SET /? and SS64 page.
Nothing is mentioned about : ~ , ! (and in fact also for - as a unary operator) and , .As they are almost obvious the parentheses also are not mentioned as logical separators ..
~ is the most strange - It acts as -(x+1) :
Code: Select all
C:\>set /a "i=~5"
-6
C:\>set /a "i=~(-5)"
4
! is the most useless -In fact I don't know if it can do anything at all - it acts as every non-arithmetic symbol and used as a unary operator converts anything to 0 :
Code: Select all
C:\>set /a "i=s7"
0
C:\>set /a "i=!7"
0
! can be used against zero.And help about << and >> seems to be not correct (check the example).
I have no idea why it's included in the help (I still hope for some uber-super-duper hidden feature).
, is the most fun (I have definitions for all of them

Code: Select all
C:\>set /a "i=1,5+3"
8
C:\>set /a "i=1,2+2"
4
C:\>set /a "i=1,2+2,j=3+2"
5
C:\>echo %i% and %j%
1 and 5
C:\>set /a "2+2"
4
Code: Select all
C:\>set /a "i=1,(2,+23)+2"
25
----------------------------
#2 16 Jan 2013 02:57
npocmaka
And three more pitfalls of set /a :
Code: Select all
C:\>set /a "a=1,b=1+%a%"
Missing operand.
Code: Select all
@echo off
setlocal ENABLEDELAYEDEXPANSION
set /a "a=1,b=1+!a!"
echo !b!
endlocal

here b will be 0 :
Code: Select all
@echo off
setlocal ENABLEDELAYEDEXPANSION
set /a "a=0"
set /a "b=!!a!"
echo !b!
endlocal
Code: Select all
@echo off
setlocal
set /a "a=5"
call set /a "b=6^%a%"
call set /a "b=6%%a%"
endlocal
#3 16 Jan 2013 05:58
carlos
npocmaka. I write that I learn in my experience with this command. The /A in set maybe means arithmetic, and means that the expression will be evaluated. Then:
Code: Select all
set "n=5"
Code: Select all
set /a "n=5"
The ! (logical negation), for work with it is neccesary turn off delayed expansion. 0 is turned 1 and all other is turned 0.
The ~ (bitwise negation) is complement.
The - (sign negation) positive sign turn negative, and negative sign turn positive.
With extensions enabled you can use the other expansion:
Is not necessary turn on delayedexpansion.
You only use the name of the variable:
Code: Select all
Set "number=10"
Set /a "new=1+number"
----------------------------
#4 16 Jan 2013 08:05
npocmaka
this was unexpected but cool ...carlos wrote:
Code: Select all
Set "number=10" Set /a "new=1+number"
Turns out that consecutive sets work after all:
Code: Select all
C:\>set /a "first=1,second=first+1"
2
Last edited by npocmaka (16 Jan 2013 11:42)
----------------------------
#5 16 Jan 2013 12:14
carlos
This is a example of use of ! operator:
Code: Select all
@Echo Off
SetLocal Enableextensions
Call :isLeap 2008
Echo 2008 : leap : %errorlevel%
Call :isLeap 2000
Echo 2000 : leap : %errorlevel%
Call :isLeap 1900
Echo 1999 : leap : %errorlevel%
Pause
Goto :Eof
:isLeap
::Author: Carlos
::Return 0 or 1 if is leap year
::Argument: year
SetLocal EnableExtensions DisableDelayedexpansion
Set /A "ly=(!(%~1%%4)&!!(%~1%%100))|!(%~1%%400)"
Exit /B %ly%
----------------------------
#6 16 Jan 2013 15:47
npocmaka
carlos wrote:
The ! (logical negation), for work with it is neccesary turn off delayed expansion. 0 is turned 1 and all other is turned 0.
Hmm.. Probably cmd.exe searches for a variable when expansion is on - and does not effect then.
More interesting SET /A does not work with DISABLEEXTENSIONS at all :carlos wrote:
With extensions enabled you can use the other expansion:
Code: Select all
@echo off
setlocal
setlocal ENABLEDELAYEDEXPANSION
set /a "test1=!0"
echo !test1!
set /a "test1=!1"
echo !test1!
endlocal
set /a "test2=!0"
echo %test2%
set /a "test2=!1"
echo %test2%
setlocal DISABLEEXTENSIONS
set /a "test5= 1 + 1"
rem will not display **2**
echo **%test5%**
endlocal
setlocal DISABLEEXTENSIONS
rem this produce error
set /a "test3=!0"
echo %test3%
set /a "test3=!1"
echo %test3%
endlocal
setlocal DISABLEEXTENSIONS ENABLEDELAYEDEXPANSION
rem this produce error too
set /a "test4=!0"
echo %test4%
set /a "test4=!1"
echo %test4%
endlocal
endlocal
----------------------------
#7 17 Jan 2013 02:17
Simon Sheppard
I've updated the SET page now, thanks for flagging this up npocmaka
----------------------------
#8 17 Jan 2013 03:20
Aacini
Comma operator allows to perform large calculations in just one line, like in this example:
Code: Select all
REM CALCULATE MONTH AND DAY OF THE EASTER SUNDAY OF THE GIVEN YEAR
SET YY=%1
SET /A A=YY%%19, B=YY/100, C=YY%%100, D=B/4, E=B%%4, F=(B+8)/25, G=(B-F+1)/3, H=(A*19+B-D-G+15)%%30, I=C/4, K=C%%4, L=((E+I)*2-H-K+32)%%7, M=(A+H*11+L*22)/451, N=H+L-M*7+114, MM=N/31, DD=N%%31+1
ECHO Easter Sunday of year %YY% is on month %MM% day %DD%
Code: Select all
SET /A D=(B=YY/100)/4, E=B%%4, G=(B-(B+8)/25+1)/3, H=((A=YY%%19)*19+B-D-G+15)%%30, K=(C=YY%%100)%%4, M=(A+H*11+(L=((E+C/4)*2-H-K+32)%%7)*22)/451, MM=(N=H+L-M*7+114)/31, DD=N%%31+1
Code: Select all
rem Copy N random numeric elements from Original to New vectors
for /L %%i in (1,1,%N%) do (
set /A index=(!random!*upperLimit)/32768+1
set /A New[!index!]=Original[!index!]
)
Code: Select all
for /L %%i in (1,1,%N%) do (
set /A index=(!random!*upperLimit)/32768+1, New[!index!]=Original[!index!]
)
Exclamation-mark (logical NOT) operator is the key to achieve conditional expressions in a way equivalent to C's conditional operator (cond)?then:else, but just for certain particular cases. For example, next line check if SIZE variable value is in range from LEFT to RIGHT (emulating an AND operation):It is interesting to note that in the evaluation of previous equation, the substitution of variable values are performed three times in the same line:Code: Select all
rem DRAWEQUATION.BAT - Draw simple equations y=f(x) in X-Y plane for /L %%x in (0,1,%maxCol%) do ( set /A "y=(Top-(%f(x)%))/yStep" . . . . )
0- Read the equation: f(x)=SIN[!x!]*20>>16
1- Normal %variable% expansion: set /A "y=%f(x)%" becomes: set /A "y=SIN[!x!]*20>>16"
2- Delayed !variable! expansion: set /A "y=SIN[!x!]*20>>16" becomes: set /A "y=SIN[1]*20>>16" (when x=1)
3- Replace variable values in SET /A command: set /A "y=1144*20>>16"
Code: Select all
set /A "C1=1,A=left-size,C1=!((A+1)/A), C2=1,A=size-right,C2=!((A+1)/A), test=C1*C2"
if %test% equ 1 (
echo Size variable is in range
) else (
echo Size variable out of range
)
Although SET /A documentation indicate that >> operator is right "logical shift" (RSH), it really operate as right "arithmetic shift" (RAS). If you need a pure logical shift, you must cancel the sign bit after the shift:
Code: Select all
C:>set /A var=-1
-1
C:>set /A "ras=var>>1"
-1
C:>set /A "rsh=var>>1&~(1<<31)"
2147483647
Antonio
----------------------------
#9 28 Oct 2013 17:21
npocmaka
set /a outputs it result without new line at the end ? yikes
Code: Select all
C:\>set /a 1 & set /a 2
12
C:\>
#10 30 Oct 2013 22:56
carlos
very interesting. that occurs in the interactive mode, almost in windows xp.npocmaka wrote:
Code: Select all
set /a outputs it result without new line at the end ? yikes C:\>set /a 1 & set /a 2 12 C:\>
----------------------------
#11 03 Mar 2015 07:20
jumper
another handy feature is that it lets you assign multiple variables at once:
Code: Select all
set /a a=b=c=d=10