Two things are required: ".BAT" extension, and a variable
named Result must be empty.
The testing loop, in (2147483647, -33554428, 0),
would count down from 2147483647, and stop on 255.
If a loop with that same speed for each number you see, it would
have calc/found that number after more than four years. In other
words: if you run the test loop (take about 4 seconds), and then
see a message: 255. "All Done", Press any key ..., then you have
displayed the same data as would have taken more than 260 years,
So, I would say this loop is fast. Besides that, it shouldn't be
a problem for you to rewrite it for whatever, other purpose than
exit-codes/errorlevels...
Benny
@echo off& setlocal enabledelayedexpansion
for /L %%I in (2147483647, -33554428, 0) do (
call :errMake %%I
call :errFind > NUL
echo !errFind!.
if "!errFind!" neq "%%I" echo OOPS.& exit /b
)
REM You could substitute the above NUL with CON
REM If NUL, Each numb was displayed in 0,06 Sec
REM 0 ... 2'31nth-1. You will not see the OOPS.
echo All Done.& pause
goto:eof
:errMake
exit /b %~1
:ErrFind
(if not defined Result set Result=%0&set Result=!Result:~1!&(if not
errorlevel 1 set !Result!=0&set Result=&goto:eof)&set H=2147483647&(if
errorlevel !H! set !Result!=!H!&set H=&set Result=&goto:eof)&set
L=0)&set/a A=H/2+L/2&echo H:!H! A:!A! L:!L!&(if errorlevel !A! ((if !L!
==!A! set H=&set/a A+=1&(if not errorlevel !A! set A=!L!)&set L=&set !
Result!=!A!&set A=&set Result=&goto:eof)&set L=!A!)else set H=!A!)&goto
%0
"for /L %%I in (2147483647, -33554428, 0) do" es executed
2147483647/33554428+1 = 65 times. What's so special when a
subroutine is executed 65 times in 4 seconds?
Herbert, for each and all 65, one could consider something like this:
if errorlevel 0 set result=0
if errorlevel 1 set result=1 ... snip ... if errorlevel 2147483647 set
result=2147483647.
Such a loop would execute 2147483648 itmes for each call.
My subroutine return each result after 0,06 seconds, so we should have
all the 65 results in 0,06 Sec * 65 = 3,9 Sec.
If we say that my subroutine is a special loop that take 0,06 Sec,
then
with that speed, "normal" looping 2147483648 times would take seconds,
X =
0,06 * 2147483648 = 128849018,9 Sec.
That is X / 60 / 60 / 24 / 365 year = 4,085775586 year.
In other words, it would take more than 4 year (or 128849018,9 Sec) to
display 2147483648 results.
Thereby 128849018,9 Sec / 2147483648 = 0,06 Sec each.
So a normal loop that should loop 2 31nth times (using that speed)
would take about 4 year for each result.
65 results would be shown in 4,085775586 * 65 = 265,5754131 year.
Compare 265 year with 4 seconds.
The special thing is that my loop don't need to loop 2147483648 times
each, but
my english maybe not good enough to explain what I think and what I
have done.
Maybe Dr. John Stockton could explain the bisection code better than
me.
Benny,
And why not a simple
set result=%errorlevel%
for /L %%I in (2147483647, -33554428, 0) do (
if "%%I"=="255" (set errorlevel=35)
call :ErrMake %%I
call :ErrFind
echo !ErrFind!. !errorlevel!
...snip...
The last output would be something like this:
255. 35
__________
All Done.
Press any key...
On Feb 20, 8:08 pm, b.peder...@get2net.dk wrote:
> On Feb 20, 7:47 pm, Herbert Kleebauer <k...@unibwm.de> wrote:
> Yes that would be okay, but If the errorlevel was set previous, like
> this: set errorlevel=something
> then it won't work. For more information, see the below label
> named :ErrMake (option numb 3).
> I admit that it could be done simple but I better like this way.
>
> Benny,
> Ps. Optimized the :ErrFind subroutine (in one line, 386 visible char
> long).
> After the endlocal, all variable used would be restored, so not need
> to empty them.
> Btw. Extension must be ".BAT", not ".CMD"
>
> @echo off
> setlocal enabledelayedexpansion
> (set Result=)
> for /L %%I in (2147483647, -33554428, 0) do (
> call :ErrMake %%I
> call :ErrFind > nul
> echo !ErrFind!.
> REM if "!ErrFind!" neq "%%I" echo OOPS.& exit /b
> )
> endlocal
> call:_& echo All Done.& pause
> goto:eof
>
> :ErrFind
> (if "!Result!"=="" set Result=%0&set Result=!Result:~1!&(if not
> errorlevel 1 set !Result!=0&set Result=&goto:eof)&set H=2147483647&(if
> errorlevel !H! set !Result!=!H!&set Result=&goto:eof)&set L=0)&set/a
> A=H/2+L/2&echo H:!H! A:!A! L:!L!&(if errorlevel !A! ((if !L!==!A! set/
> a A+=1&(if not errorlevel !A! set A=!L!)&set !Result!=!A!&set
> Result=&goto:eof)&set L=!A!)else set H=!A!)&goto%0
>
> :ErrMake X [norm/both/user]
> if /i "%~2"=="norm" (set errorlevel=)
> if /i "%~2"=="both" (set errorlevel=%~1)
> if /i "%~2"=="user" (
> cd.\&(set errorlevel=& if errorlevel 1 exit /b %~1
> call:_
> echo It is recognizable that a variable errorlevel
> echo have been manipulated, value is %errorlevel%.
> echo.
> echo "%~nx0" is ready to create the exit-code %~1,
> echo Please make a choice, 1...3:
> echo.
> echo 1: As requested, create an ERRORLEVEL %~1
> echo.
> echo 2: Also set the synthetic errorlevel variable
> echo.
> echo 3: Normalize/restore the synthetic errorlevel
> echo so it is following the real DOS ERRORLEVEL
> echo.&(set /p errorlevel=?: )
> (set errorlevel=%errorlevel%)
> if "!errorlevel!"=="2" (set errorlevel=%~1)
> if "!errorlevel!"=="3" (set errorlevel=))
> )
> exit /b %~1
> :_
> for %%_ in (________________) do (echo %%_%%_%%_%%_%%_)
> Yes that would be okay, but If the errorlevel was set previous, like
> this: set errorlevel=something
> then it won't work.
set e=%errorlevel%
set errorlevel=
set result=%errorlevel%
set errorlevel=%e%
echo %errorlevel%
echo %result%
Yes ofcause, Anyhow, I would prefer just take the errorlevel by IF
ERRORLEVEL X ...
as in the good old days.
Benny,
Btw: Since I found a bug in my previous post (ErrMake), it's now
deleted.
The updated subroutines are included below.
Yes that would be okay, but If the errorlevel was set previous, like
this: set errorlevel=something
then it won't work. For more information, see the below label
named :ErrMake (option numb 3).
I admit that it could be done simple but I better like this way.
Benny,
Ps. Optimized the :ErrFind subroutine (in one line, 386 visible char
long).
After the endlocal, all variable used would be restored, so not need
to empty them.
Btw. Extension must be ".BAT", not ".CMD"
@echo off
setlocal enabledelayedexpansion
(set Result=)
for /L %%I in (2147483647, -33554428, 0) do (
call :ErrMake %%I
call :ErrFind > nul
echo !ErrFind!.
REM if "!ErrFind!" neq "%%I" echo OOPS.& exit /b
)
endlocal
call:_& echo All Done.& pause
goto:eof
:ErrFind
(if "!Result!"=="" set Result=%0&set Result=!Result:~1!&(if not
errorlevel 1 set !Result!=0&set Result=&goto:eof)&set H=2147483647&(if
errorlevel !H! set !Result!=!H!&set Result=&goto:eof)&set L=0)&set/a
A=H/2+L/2&echo H:!H! A:!A! L:!L!&(if errorlevel !A! ((if !L!==!A! set/
a A+=1&(if not errorlevel !A! set A=!L!)&set !Result!=!A!&set
Result=&goto:eof)&set L=!A!)else set H=!A!)&goto%0
:ErrMake X [norm/both/user]
if /i "%~2"=="norm" (set errorlevel=)
if /i "%~2"=="both" (set errorlevel=%~1)
if /i "%~2"=="user" (
cd.\&(set errorlevel=& if errorlevel 1 exit /b %~1
call:_
echo It is recognizable that a variable errorlevel
echo have been manipulated, value is %errorlevel%.
echo.
echo "%~nx0" is ready to create the exit-code %~1,
echo Please make a choice, 1...3:
echo.
echo 1: As requested, create an ERRORLEVEL %~1
echo.
echo 2: Also set the synthetic errorlevel variable
echo.
echo 3: Normalize/restore the synthetic errorlevel
echo so it is following the real DOS ERRORLEVEL
echo.& (set /p errorlevel=?: )
if "!errorlevel!"=="3" set errorlevel=&exit /b %~1
if "!errorlevel!"=="2" (set errorlevel=%~1) else (
set errorlevel=%errorlevel%))
Herbert, when I started this project, I found lot of
strange things. Behaviour that was depending on
files extension CMD or BAT and when the errorlevel
variable is set empty, like this:
(set errorlevel=), then a new errorlevel value
is set...
Now it all seems less confusing :-)
Benny
> and when the errorlevel
> variable is set empty, like this:
> (set errorlevel=), then a new errorlevel value
> is set...
This is true only for .cmd files. In .bat files the errorlevel
is only set if you try to unset a varibale which isn't set.
Unset a variable which isn't set was previous said as
Setting an Empty variable to Empty (EE)
would set ERR 1. All other
settings, (EX XX XE) would set CMD ERR 0, but
leave BAT ERR unchanged.
Maybe bad english but the :ErrMake subroutine should work
in both CMD or BAT files....
Herbert, both my subroutines (ErrMake and ErrFind) is finished :-)
I you want, we could discuss some of the other SET things, such as
() ! ~ - * / % + - << >> & ^ |
= *= /= %= += -=
&= ^= |= <<= >>= ,
ex. I couldn't get the &= thing to work....
Benny