#1 18 Mar 2020 15:36

tomsuters
New Member
Registered: 18 Mar 2020
Posts: 3

32 bit numbers 0x80000000 vs. -2147483648

:: is the following a known CMD feature or bug? Is there a way around this?

:: the first assignment in decimal notation gives an 'invalid number' error, 
:: the second assignment in hexadecimal notation works and displays the (correct) value in decimal notation
:: the third assignment again returns an 'invalid number' error!
:: the error seems to occur only with the max negative value for 32 bit 2's complement numbers
set /a "$x=-2147483648"
set /a "$x=0x80000000"
set /a "$y=(%$x% & 1)

:: the following works fine 
set /a "$x=-2147483647"
set /a "$x=0x80000001"
set /a "$y=(%$x% & 1)

:: the following also works fine 
set /a "$x=2147483647"
set /a "$x=0x0FFFFFFF"
set /a "$y=(%$x% & 1)

Offline

#2 18 Mar 2020 19:41

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 1,079
Website

Re: 32 bit numbers 0x80000000 vs. -2147483648

This is arguably a bug in CMD, but the cause is the way that two's complement mathematics handles the lowest negative number:
https://en.wikipedia.org/wiki/Two%27s_c … ive_number

Offline

#3 19 Mar 2020 12:01

tomsuters
New Member
Registered: 18 Mar 2020
Posts: 3

Re: 32 bit numbers 0x80000000 vs. -2147483648

Hello Simon, thx for your reply.

I guess it shows that CMD handles bitwise operations as arithmetic on signed numbers (including overflow detection) iso boolean operations on unsigned numbers which is what you want/expect logical operators to do. Anyway, that's the way it is.

I came across this issue using a number as a 32-bit bitmask or status register. It is now clear you can only use 31 bits (all but the sign bit) for this. Using the sign bit as a status bit too will lead to what at first seems to be a very strange unexpected CMD error causing your script to fail. Hope this thread prevents others to fall into the same trap!

Tom Suters

Offline

Board footer

Powered by FluxBB