Page 1 of 1
New behavior with SET /A?
Posted: 05 Oct 2012 17:35
by dbenham
I just discovered some SET /A behavior that is new for me. (assume all variables are cleared before each example)
1) Extra spaces are ignored in both the name and the value. This one does not surprise me much.Normally, extra spaces in a SET statement are incorporated into the name and/or value.
Code: Select all
C:\test>set var1 = 33
C:\test>set var1
var1 = 33
But extra spaces in SET /A are ignored
Code: Select all
C:\test>set /a var1 = 33
33
C:\test>set var1
var1=33
2) A single computation can perform multiple assignments if parentheses are used. This one is a very pleasant surprise
Code: Select all
C:\test>set /a var1=33
33
C:\test>set var2=
C:\test>set var
var1=33
C:\test>set /a var1+=(var2=10)
43
C:\test>set var
var1=43
var2=10
Dave Benham
Re: New behavior with SET /A?
Posted: 05 Oct 2012 19:07
by Liviu
dbenham wrote:2) A single computation can perform multiple assignments if parentheses are used. This one is a very pleasant surprise
Neat! And now, for the obligatory abuse of such surprise, the following appears to work as an 8th power shorthand

Code: Select all
@echo off &setlocal enableDelayedExpansion
set /a v1=2
set /a v1*=(v1*=(v1*=v1)) & echo %v1%*=(%v1%*=(%v1%*=%v1%)) == !v1!
On a more serious note, it does indeed appear that the order of evaluation is inner paranthesis first, and left to right among peers.
Code: Select all
set /a v1=2
set /a v1*=(v1+=1)*(v1+=3) & echo %v1%*=(%v1%+=1)*(%v1%+=3) == !v1!
- with v1=2, v1+=1 sets v1 to 3;
- with v1=3, v1+=3 sets v1 to 6;
- with v1=6, v1*=3*6 gives 108.
Liviu
Re: New behavior with SET /A?
Posted: 05 Oct 2012 22:36
by dbenham
Very nice - those examples might give a few people a headache
Liviu wrote:On a more serious note, it does indeed appear that the order of evaluation is inner paranthesis first, and left to right among peers.
Yes - One of the rare cases where the HELP documentation does a good job. The order of precedence is well documented.
Code: Select all
C:\test>HELP SET
...
... The expression evaluator is pretty simple and supports the following
operations, in decreasing order of precedence:
() - grouping
! ~ - - unary operators
* / % - arithmetic operators
+ - - arithmetic operators
<< >> - logical shift
& - bitwise and
^ - bitwise exclusive or
| - bitwise or
= *= /= %= += -= - assignment
&= ^= |= <<= >>=
, - expression separator
...
Dave Benham
Re: New behavior with SET /A?
Posted: 06 Oct 2012 00:42
by Liviu
dbenham wrote:One of the rare cases where the HELP documentation does a good job. The order of precedence is well documented.
Sorry, can't let that pass unchallenged

yes, the precedence is well defined, but the "associativity and order of evaluation" is not. Turns out that, for math operators at least, it is indeed left to right (otherwise the result below wouldn't be 1333).
Code: Select all
set /a v1=0 & set /a v1+=(v1+=1)+(v1+=10)*(v1+=100) &echo !v1! &rem v1 == 1333
But, for example, the assignment operators (=, += etc) "associate" right to left.
Code: Select all
set /a w1 = w2 = 1 & echo w1 = !w1!, w2 = !w2! & rem w1 = 1, w2 = 1
set /a w1 += w2 += 1 & echo w1 = !w1!, w2 = !w2! & rem w1 = 3, w2 = 2
set /a w1 += w2 = 1 & echo w1 = !w1!, w2 = !w2! & rem w1 = 4, w2 = 1
set /a w1 = w2 += 1 & echo w1 = !w1!, w2 = !w2! & rem w1 = 2, w2 = 2
Liviu
Re: New behavior with SET /A?
Posted: 08 Oct 2012 09:11
by walid2mi
hi,
you can also us this syntax for multi assignement:
or for count words:
Code: Select all
CMD I> set W=sample test string hello world
CMD I> set/A X=1+%W: =,X+=1+%
5
or for using without enable delayed expansion
Code: Select all
CMD I> set T=10
set S=20
set /a N= T * S
or inject value in another var:
Code: Select all
CMD I> set a=60,b=20
for /f %%x in ('"set /a (a-b)/4"') do set c=%%x
...etc
sorry for my english
Re: New behavior with SET /A?
Posted: 27 Oct 2012 01:04
by Aacini
The expression separator operator (comma) allows to achieve multiple variable assignments with no parentheses:
Previous line execute faster than three separate SET or SET /A commands. Several comma operators in the same SET /A command are executed from left to right:
Code: Select all
set /A T=10, S=20, N= T * S
set /A a=60,b=20, c=(a-b)/4
This feature allows to write complex algebraic expressions in just one SET /A command that execute much faster than individual commands,
for example:
Code: Select all
:EasterSunday year
rem Calculate the date of Christian Easter Sunday of any given year
rem Antonio Perez Ayala
set /A A=%1%%19, B=%1/100, C=%1%%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
set /A K=C%%4, L=((E+I)*2-H-K+32)%%7, M=(A+H*11+L*22)/451, N=H+L-M*7+114, Month=N/31, Day=N%%31+1
echo %Month%/%Day%/%1
Antonio
Re: New behavior with SET /A?
Posted: 27 Oct 2012 08:13
by dbenham
@Aacini. Sure, I've been doing that with commas for a long time. I was considering it a separate computation after the comma (yes, faster then individual SET /A commands, less typing as well).
But putting multiple assignments in one computation using parentheses (without commas) opens up some interesting possibilities, as Liviu has demonstrated. I had never tried it before and was surprised it worked.
Dave Benham