SET /A overflow

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

SET /A overflow

#1 Post by einstein1969 » 07 Apr 2014 14:38

Hi to all,

There is a method for detect "programmatically" an overflow for simple expressions?

for example:

Code: Select all

set /a T=A*B


This is the complete code:

Code: Select all

@echo off & setlocal

rem Tested on windows 7 32bit
rem Tested on positive numbers

:start

Call :input A

Call :input B

Echo(
Echo Calculating %A%*%B%
set /a T=%A%*%B%

Echo Result: %T%

exit /b


:input
rem MAX 2147483647

set "Retry=& pause & goto :input"
set "Out=echo Number exceeds 2147483647 %Retry%"

set Num=
set /p "Num=Insert an integer number>"
if not defined Num set Num=%random%%random% & call echo Random number  %%Num%%

(if errorlevel %Num% call ) >nul 2>&1||(Echo Not valid number! %Retry%)

if %Num% geq 2147483647 if not "%Num%"=="2147483647" %Out%

rem if there are other errors...
set /a %1=%Num% 2>nul
if %errorlevel% equ 1073750992 %Out%

set /a %1=Num

exit /b


einstein1969

penpen
Expert
Posts: 1997
Joined: 23 Jun 2013 06:15
Location: Germany

Re: SET /A overflow

#2 Post by penpen » 07 Apr 2014 16:36

This may help you:

Code: Select all

@echo off
set /A "A=-0x10000"
set /A "B= 0x8000"

set /A "A=-1"
set /A "B=-1"
:: needs A <= B
if NOT %A% EQU %B% if NOT %B% EQU 0x7FFFFFFF if %B% LSS %A% (
   set "A=%B%"
   set "B=%A%"
)

if 0 LSS %A% (set "signum_A=1") else set "signum_A=-1"
if 0 LSS %B% (set "signum_B=1") else set "signum_B=-1"

if %A% == -1 (
   set /A "test=0x7FFFFFFF"
) else if NOT %signum_A% == %signum_B% (
   set /A "test=0x80000000/A"
) else if %signum_A% == -1 (
   set /A "test=0x80000000/A"
) else (
   set /A "test=0x7FFFFFFF/A"
)

if %test% EQU 0x7FFFFFFF (
   echo no overflow
) else if %B% GEQ %test%  (
   echo overflow
) else (
   echo no overflow
)
goto :eof

penpen

Edit: Corrected the algorithm, because (0x80000000/-1) has no positive representation.
In addition worked around the bug: "if 2147483647 LSS -1 echo true" echoes "true" on windows xp home 32 bit (?!)
Last edited by penpen on 08 Apr 2014 02:08, edited 1 time in total.

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: SET /A overflow

#3 Post by einstein1969 » 07 Apr 2014 18:20

thanks! You are a genius! 8) :D

I'm getting crazy with this: :evil:

Code: Select all

>set /a -2147483648
Numero non valido. I numeri possono avere una precisione massima di 32 bit.

>set /a 0x80000000/1
-2147483648

>set /a 0x80000000/-1
Numero non valido. I numeri possono avere una precisione massima di 32 bit.


when i check overflow for A=-1 and B=-1

:shock:

einstein1969

penpen
Expert
Posts: 1997
Joined: 23 Jun 2013 06:15
Location: Germany

Re: SET /A overflow

#4 Post by penpen » 08 Apr 2014 02:13

Sorry my fault: I've not realized that -0x80000000/-1 has no positive representation.
I also realized that "if 2147483647 LSS -1 echo true" echoes "true", at least on my win xp home 32 bit ?!
I've changed the algorithm to fix both issues.
I hope it is bug free now.

penpen

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: SET /A overflow

#5 Post by einstein1969 » 08 Apr 2014 16:17

... so ABS(-2147483648) do not exists? :?

einstein1969

penpen
Expert
Posts: 1997
Joined: 23 Jun 2013 06:15
Location: Germany

Re: SET /A overflow

#6 Post by penpen » 09 Apr 2014 12:09

It does exist, but it is a 32 bit cyclic subspace of the natural numbers in two's-complement, so --2147483648 == -2147483648

Code: Select all

set /A "-0x80000000"
-2147483648

penpen

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: SET /A overflow

#7 Post by Aacini » 09 Apr 2014 16:36

einstein1969 wrote:... so ABS(-2147483648) do not exists? :?

einstein1969


Yes, that's right: +2147483648 does not exists as a 32 bits number. We would need at least one bit more in order for the sign bit be zero.

Antonio

Post Reply