0

I got a batch script with a block of code as:

@echo off
setlocal EnableDelayedExpansion
rem US locale, ie: 'Thu 12/02/2015'
for /F "tokens=2 delims=/ " %%m in ("%date%") do set /A "n=(3*((1%%m)%%100-1))"
echo %n%
pause

and while I was trying to understand it, I landed writing it myself as:

@echo off
setlocal EnableDelayedExpansion
rem US locale, ie: 'Thu 12/02/2015'
for /F "tokens=2 delims=/ " %%m in ("%date%") do set /A "n=3*(%%m-1)"
echo %n%
pause

Since both returns 33 as output, can anyone please help me understand the logic behind "n=(3*((1%%m)%%100-1))" and the difference between both the blocks.

2 Answers 2

3
3*((1%%m)%%100-1)

%%m is 12 in this example, resulting in

3*((112)%%100-1)

let's get rid of the redundant parantheses and add some spaces for better readabiltiy:

3 * ( 112 %% 100 ) - 1

evaluated:

3 * (     12     ) - 1

%% is the "Modulo" Operator - it gives back the rest when dividing the first number throug the second one (112 Modulo 100 is (1*100) rest 12) (NOTE: if you try this on commandline instead of inside a batchfile, use a single % only)

This seems to be ridiculous, but think, your number isn't 12, but 09. Numbers starting with Zero are handled as octal, but 09(octal) isn't a valid number, so you'll get a Syntax error.

Same walkthrough with 09 instead of 12:

3*((109)%%100-1)
3 * ( 109 %% 100 ) - 1
3 * (      9     ) - 1

The last line without the Modulo trick would be:

3 * (     09     ) - 1

As 09 is not a valid number (there is no 9 in octal numbers), this wouldn't work.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! That's a great explanation... :)
0

It's possible that the digit-group being processed is "08" or "09".

Batch assumes that a leading "0" means that the following string is octal not decimal and objects to 8 or 9 since they are not octal digits.

the method prefixes a "1" amking "108" or "109" which are bot valid decimal numbers that do not start "0" and hence will be interpreted as decimal.

Since 100 is added to each of the numbers 01..12 then you add 100, you need to remove that 100, so %%100 does that (calculate mod-100 = 1..12)

Another way would be to subtract 100, obviously.

(assuming the group is a month. If it's a *day** as it would appear, the same argument applies, but the limits are 01..31 or 1..31.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.