Page 1 of 2
Fastest way to get number of decimal digit
Posted: 23 Mar 2014 09:09
by einstein1969
Hi to all,
I need to count the number of char in a string. This is the lenght of the string.
But the string that i use is composed from only decimal digit (0123456789) and the lenght max is 9.
examples of numbers:
Code: Select all
set N1=123456789
set N2=5604
set N3=0
what is the fastest way?
einstein1969
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 09:54
by foxidrive
Test these:
Code: Select all
@echo off
set pre=.abc
for /f "tokens=1* delims=:" %%a in (
'^(for %%i in ^("%pre%" .^) do @echo %%i^) ^| findstr /o .^| findstr /v /b 0') do set /a var=%%~a-5
Code: Select all
@echo off
:: Space char. substitution below (I used a period) was necessary as when %* or %VAR% is expanded by
:: the for-in-do below, it concatenated any number of sequential spaces to 1 space destroying an
:: accurate count
set "VAR=%*"
set "var=%var: =.%"
for /f "delims=[] tokens=1" %%l in (
'cmd /u /c echo/%VAR%^|find /v /n ""') do set /a CNT=%%l-3
if %CNT% EQU -3 set CNT=0
echo %CNT%
pause
Code: Select all
@echo off
set "string=aaa bbb ccc"
call :a abc string
echo %abc%
pause
goto :EOF
:a
(
setlocal EnableDelayedExpansion
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
set "%~1=%len%"
exit /b
)
Code: Select all
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for %%a in (*.txt) do (
set "name=%%~na"
call :strlen name len
rem if !len! GTR 7 del "%%a"
)
pause
goto :eof
:strLen string len -- returns the length of a string
:: -- string [in] - variable name containing the string being measured for length
:: -- len [out] - variable to be used to return the string length
:: Many thanks to 'sowgtsoi', but also 'jeb' and 'amel27' dostips forum users helped making this short and efficient
:$created 20081122 :$changed 20101116 :$categories StringOperation
:$source http://www.dostips.com
( SETLOCAL ENABLEDELAYEDEXPANSION
set "str=A!%~1!"&rem keep the A up front to ensure we get the length and not the upper bound
rem it also avoids trouble in case of empty string
set "len=0"
for /L %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
)
( ENDLOCAL & REM RETURN VALUES
IF "%~2" NEQ "" SET /a %~2=%len%
)
EXIT /b
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 10:43
by aGerman
I think foxis 3rd approach could be easily improved to meet your expectations.
Code: Select all
@echo off
set "num=987654321"
setlocal EnableDelayedExpansion
set /a "n=1%num%, len=0"
for %%P in (8 4 2 1) do (
if "!n:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "n=!n:~%%P!"
)
)
endlocal &set "len=%len%"
echo %len%
pause
Regards
aGerman
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 12:34
by einstein1969
@foxidrive
thanks! you are very exhaustive.
I have tested and the fastest is 3rd approach as said aGerman
@aGerman
thanks, the for %%P in (8 4 2 1) do .. is more faster.
I have broken down and this is the result:
Code: Select all
@echo off
set "num=987654321"
setlocal EnableDelayedExpansion
set /a "n=1!num!, len=0"
if "!n:~8,1!" NEQ "" set /a "len=8, n/=100000000"
if "!n:~4,1!" NEQ "" set /a "len+=4, n/=10000"
if "!n:~2,1!" NEQ "" set /a "len+=2, n/=100"
if "!n!" geq "0" set /a "len+=1"
endlocal &set "len=%len%"
echo %len%
but i thinks that is possible to optimize yet.
EDIT: this approch do not WORK!
einstein1969
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 13:13
by penpen
How about this:
Code: Select all
@echo off
setlocal enableDelayedExpansion
set "$numLength=set "length=0123456789^^^!num^^^!"&set "length=^^^!length:~-10,1^^^!""
set "num=1234567"
%$numLength%
echo(length=%length%
endlocal
penpen
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 13:24
by aGerman
@einstein1969
almost right except of the last if statement. You don't need the delayed expansion btw.
Code: Select all
set /a "n=1%num%, len=0"
if "%n:~8,1%" NEQ "" set /a "len=8, n/=100000000"
if "%n:~4,1%" NEQ "" set /a "len+=4, n/=10000"
if "%n:~2,1%" NEQ "" set /a "len+=2, n/=100"
if "%n:~1,1%" NEQ "" set /a "len+=1"
@penpen
very clever
Just two lines of code without macro and without delayed expansion. Unbeatable.
Code: Select all
set "len=0123456789%num%"
set "len=%len:~-10,1%"
Regards
aGerman
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 13:59
by einstein1969
I agree! Unbeatable.
thanks penpen.
einstein1969
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 15:03
by einstein1969
The code was necessary for this but I found another solution.
But I think I will be useful for the other operation. It is possible to check if the lenght of "ops" is less than 19?
You see some optimization to do for this code?
This is fast(use only one SET) add of two natural of max 18 digit (useful also for real fixed point operation)
Code: Select all
@echo off & setlocal EnableDelayedExpansion
set op1=292942778123198
set op2=294822282920383
for /f "tokens=1* delims=0 " %%a in ("A0!op1:~-9!") do for /f "tokens=1* delims=0 " %%c in ("A0!op2:~-9!") do for /f "tokens=1-2" %%h in ("!op1:~0,-9! !op2:~0,-9! 0 0") do (
set /a "t1=((%%b+(%%d+0)) %% 1000000000)+1000000000, t2=((%%b+(%%d+0)) / 1000000000+(%%h+0)+(%%i+0))"
for /f "tokens=1* delims=0 " %%e in ("A0!t2!!t1:~-9!") do if "%%f" == "" (echo Tot=0) else echo Tot:%%f
)
Res:
einstein1969
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 15:40
by aGerman
It is possible to check if the lenght of "ops" is less than 19?
You could use the same technique.
Code: Select all
set "check=x%op1%"
set "check=%check:~-19,1%"
echo %check%
check will only be "x" if the length is less than 19.
Regards
aGerman
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 16:20
by einstein1969
thanks aGerman! It work!
einstein1969
Re: Fastest way to get number of decimal digit
Posted: 23 Mar 2014 17:09
by penpen
You could avoid all for loops on "op1+op2" (unoptimized);
i hope this is faster (could also be used in a macro to additional speed up, too):
Code: Select all
@echo off
setlocal
set "op1=292942778123198"
set "op2=294822282920383"
set "a=000000000%op1:~-9%"
set "c=000000000%op2:~-9%"
set /A "t2=((ac=(1%a:~-9%-1000000000)+(1%c:~-9%-1000000000))/1000000000)+(%op1:~0,-9%+0)+(%op2:~0,-9%+0)"
if "%t2%" == "0" (
set "t2="
set "t1=%ac%"
) else (
set "t1=000000000%ac%"
)
set "f=%t2%%t1:~-9%"
echo Tot: %f%
endlocal
goto :eof
penpen
Edit: Corrected a bug on trailing 0's.
Edit2: Replaced the missing lines of the code, too; should work now... .
Re: Fastest way to get number of decimal digit
Posted: 24 Mar 2014 11:21
by einstein1969
Hi penpen,
you have missed some.... what is %ac%?
i like see other vision of same problem. It expand and make flexible memory. Thanks!!!
For the macro i like
this approch:
einstein1969
Re: Fastest way to get number of decimal digit
Posted: 24 Mar 2014 15:53
by Compo
I don't really understand why speed of execution for an initial input parameter of up to nine digits is so important so here's my basic solution regardless of speed:
Code: Select all
@Echo Off&SetLocal EnableDelayedExpansion
Set "_=%*"&Set "_n=0"
For %%a In (0 1 2 3 4 5 6 7 8 9) Do Set _=!_:%%a=%%a !
For %%a In (%_%) Do Set/a _n+=1
Echo(%_n% digits&Ping -n 6 127.0.0.1 1>Nul
just run it with the digits as an input parameter e.g.
X:\ScriptDir>runbatch.cmd 683673295321065
15 digits
Re: Fastest way to get number of decimal digit
Posted: 25 Mar 2014 09:18
by einstein1969
Compo wrote:I don't really understand why speed of execution for an initial input parameter of up to nine digits is so important so here's my basic solution regardless of speed:
Code: Select all
@Echo Off&SetLocal EnableDelayedExpansion
Set "_=%*"&Set "_n=0"
For %%a In (0 1 2 3 4 5 6 7 8 9) Do Set _=!_:%%a=%%a !
For %%a In (%_%) Do Set/a _n+=1
Echo(%_n% digits&Ping -n 6 127.0.0.1 1>Nul
just run it with the digits as an input parameter e.g.
X:\ScriptDir>runbatch.cmd 683673295321065
15 digits
Thanks Compo for your apport.
Reguard the speed of execution of initial imput parameter, you are right if the rest of the code is expensive/wasteful. In such a case would be negligible.
einstein1969
Re: Fastest way to get number of decimal digit
Posted: 25 Mar 2014 11:07
by penpen
Sorry, last time i have replaced only the second half of the code although i've rewritten more
.
I've changed the above code, so it should work now (i hope).
To speed up even more, you could make a macro of it; also you may use lesser variables.
penpen