Firstly, this is an XY problem because Windows already has a command for counting down: timeout
. There's no reason to re-implement that unless you want more control over it
Regarding the observed behavior, cmd.exe (as well as its set /a
internal command) uses only 32-bit integers, therefore the maximum value it can represent is 2147483647 = 232 - 1
The numbers must all be within the range of 32 bit signed integer numbers (-2,147,483,648 through 2,147,483,647) to handle larger numbers use PowerShell or VBScript.
https://ss64.com/nt/set.html
It's an extremely common constant in computers, since we almost all use 32-bit int. The correlation to Mersenne prime is just purely accidental due to the choice of bit width
And from the above link you can see comma is a separator operator just like in C-like languages, not a radix point. In fact I've never seen a programming language that uses comma as radix point like in written languages.
,
Commas separate expressions set /a "_num=2,_result=_num*5"
If you run set /?
you'll see the comma in the precedence table
The /A switch specifies that the string to the right of the equal sign
is a numerical expression that is evaluated. 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
That means 1037950429,999999999*60
is simply 2 expressions, one calculates 1037950429
and discard, and the other calculates 999999999*60
, which overflows 32-bit int and returns a negative value as you see
C:\Users\>set /a 1037950429,999999999*60
-129542204
C:\Users\>set /a 999999999*60
-129542204
C:\Users\>set /a 1037950429,99999999*60
1705032644
C:\Users\>set /a 99999999*60
1705032644
C:\Users\>set /a 1037950429.999999999*60
Missing operator.
Even if you want to do operations with floating-point values such as 1037950429.999999999
then you're out of luck since that exceeds the precision of the biggest binary floating-point type in VBS and PowerShell which is IEEE-754 double precision and can only be accurate to ~15 decimal digits. PowerShell does have a 128-bit decimal floating-point type (inherited from .NET's decimal) that helps a bit in that case though:
PS C:\Users> 1037950429.999999999d * 60
62277025799.999999940
Also note that set a = b
in batch means assigning a string b
with a space before into a variable named %a %
. Spaces are significant in set
command, thus don't use spaces around the =
operator. See