thanks aGerman
I have merged and optimized but there are some question on this part of code:
Code: Select all
1: if "%f:~0,1%" == "-" (
2: set f=%f:~1%
3: set i=!f:*.=!!zero:~0,%prec%!& if not "!f:*.=!" == "!f!" set i=!f:.%f:*.=%=!!i:~0,%prec%!
4: FOR /F "tokens=* delims=0" %%z IN ("!i!") DO SET /a "i=(((%%z+0)+5)/10)*-(((-i>>31)&2)-1)"
5: )
1) On line 2 i remove the sign but in line 3 i use %f:*.=% for removing the part before the decimal. The question is that is in a block () and the expansion should not work, i think...
2) on line 4 the FOR that remove the leading zero , in such cases it may not perform the set?
The new code:
Code: Select all
@echo off & setlocal EnableDelayedExpansion
:Main
echo( Input F2I FPTOINT FP2INT FP2INT-Alt
For %%r in (3 0 0.1 0.6 .1 .6 0.0001 0.0006 3.1 3.6 3.0 3.0002 3.02 3.000 30 1.083 1.087 1.0837 0.07 0.09 9 0.9 09.09) do (
set xr0=%%r
call :F2I xr0 3
set nxr0=-%%r
call :F2I nxr0 3
call :FPTOINT %%r xr1 3
call :FPTOINT -%%r nxr1 3
set xr2=%%r
call :FP2INT xr2 3
set nxr2=-%%r
call :FP2INT nxr2 3
call :FP2Int %%r 3 xr3
call :FP2Int -%%r 3 nxr3
::Pad
set p= %%r/-%%r&<nul set /p ".='!p:~-16!"
For %%p in (!xR0!/!nxR0! !xr1!/!nxr1! !xr2!/!nxr2! !xr3!/!nxr3!) do (set p= %%p&<nul set /p ".='!p:~-14!")
echo(
)
rem preload cpu for "CPU throttling"
for /l %%l in (1,1,200000) do rem
echo(
echo Timing F2I...
set a0=%time%
for /l %%l in (1,1,100) do (
For %%r in (3 0 0.1 0.6 .1 .6 0.0001 0.0006 3.1 3.6 3.0 3.0002 3.02 3.000 30 1.083 1.087 1.0837 0.07 0.09 9 0.9 09.09) do (
set nx=%%r
call :F2I nx 3
echo !nx! > nul
set nx=-%%r
call :F2I nx 3
echo !nx! > nul
)
)
set a1=%time%
call :difftime a0 a1
echo(
echo Timing FPTOINT...
set a0=%time%
for /l %%l in (1,1,100) do (
For %%r in (3 0 0.1 0.6 .1 .6 0.0001 0.0006 3.1 3.6 3.0 3.0002 3.02 3.000 30 1.083 1.087 1.0837 0.07 0.09 9 0.9 09.09) do (
call :FPTOINT %%r nx 3
echo !nx! > nul
call :FPTOINT -%%r nx 3
echo !nx! > nul
)
)
set a1=%time%
call :difftime a0 a1
echo(
echo Timing FP2INT...
set a0=%time%
for /l %%l in (1,1,100) do (
For %%r in (3 0 0.1 0.6 .1 .6 0.0001 0.0006 3.1 3.6 3.0 3.0002 3.02 3.000 30 1.083 1.087 1.0837 0.07 0.09 9 0.9 09.09) do (
set nx=%%r
call :FP2INT nx 3
echo !nx! > nul
set nx=-%%r
call :FP2INT nx 3
echo !nx! > nul
)
)
set a1=%time%
call :difftime a0 a1
echo(
echo Timing FP2INT... Alternate input method
set a0=%time%
for /l %%l in (1,1,100) do (
For %%r in (3 0 0.1 0.6 .1 .6 0.0001 0.0006 3.1 3.6 3.0 3.0002 3.02 3.000 30 1.083 1.087 1.0837 0.07 0.09 9 0.9 09.09) do (
call :FP2INT %%r 3 nx
echo !nx! > nul
call :FP2INT -%%r 3 nx
echo !nx! > nul
)
)
set a1=%time%
call :difftime a0 a1
Goto :Eof
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Merged and optimized (not using 1%%a-(11%%a-1%%a)/10 because limited to precision 8)
:: thanks to aGerman, penpen for trick in ieee work
:: Max Precision 9-10, rounding, beta!
:: From F.P. aka Einstein1969
:FP2INT
setlocal EnableDelayedExpansion
set zero=0000000000& set /a Prec=%2+1
if "%~3" NEQ "" (set f=%~1) else set f=!%~1!
if "%f:~0,1%" == "-" (
set f=%f:~1%
set i=!f:*.=!!zero:~0,%prec%!& if not "!f:*.=!" == "!f!" set i=!f:.%f:*.=%=!!i:~0,%prec%!
FOR /F "tokens=* delims=0" %%z IN ("!i!") DO SET /a "i=(((%%z+0)+5)/10)*-(((-i>>31)&2)-1)"
) else (
set i=!f:*.=!!zero:~0,%prec%!& if not "!f:*.=!" == "!f!" set i=!f:.%f:*.=%=!!i:~0,%prec%!
FOR /F "tokens=* delims=0" %%z IN ("!i!") DO SET /a "i=((%%z+0)+5)/10"
)
endlocal & if "%~3" NEQ "" (SET %~3=%i%) else IF "%~1" NEQ "" SET %~1=%i%
goto :Eof
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::Extended Aacini to work on "not well written" number, not rounding, not optimized.
:FPTOINT I.F INT=
setlocal EnableDelayedExpansion
set num=%1
set sign=
if %num:~0,1% == - set num=%num:~1%& set sign=-
rem prec
set nnn=&for /l %%n in (1,1,%~3) do set nnn=!nnn!0
if not "%num%"=="%num:.=%" (set fnum=%num:*.=%) else (set num=!num!.%nnn%&set fnum=%nnn%)
set inum=!num:.%fnum%=!
if not defined inum set inum=0
set fnum=!fnum!%nnn%
set fnum=!fnum:~0,%3!
set num=!inum!.!fnum!
rem set /a mul=1%nnn%, num=(inum*mul+1!fnum!-mul), num=%sign%num
set num=%num:.=%
:removeLeftZeros
if %num:~0,1% == 0 set num=%num:~1%& if defined num goto removeLeftZeros
if not defined num set num=0& set sign=
endlocal & set %2=%sign%%num%
exit /B
:: Extended to manage negative number. Not implemented remove leading zero, not optimized.
:F2I -- float to integer
: -- %~1: var ref, for in place conversion
: -- %~2: precision
SETLOCAL
set f=!%~1!
if %f:~0,1% == - (set f=%f:~1%& set sign=-) else set sign=
set /a prec=%~2 + 1&rem.--keep one more for rounding
set nnn=&for /l %%n in (1,1,%prec%) do set nnn=!nnn!0
set mul=1%nnn%
for /f "tokens=1,2 delims=. " %%a in ("%f%") do (set f1=%%a&set f2=%%b%nnn%)
set f2=1!f2:~0,%prec%!&rem.--HexCludge--need the 1 up front to not be confused with hex
set /a i=f1*mul+f2
set /a i+=5&rem.--ensure correct rounding
set /a i-=mul&rem.--HexCludge--need to subtract the 1 added earlier
set i=%i:~0,-1%
if not defined i set i=0&set sign=
(ENDLOCAL & REM.-- RETURN VALUES
IF "%~1" NEQ "" SET %~1=%sign%%i%
)
GOTO:EOF
::_____________________________________________________________
:difftime t1var t2var [result]
::
:: Usage:
:: set "t1=%time%"
:: rem do some stuff
:: set "t2=%time%"
:: Call :difftime t1 t2
::
:: added a simple check for input error
::
:: The quote(") in set are necessary for problem with space at the end of line.
:: This function replace space with zero (0) for the hours from 0:00:00,00 to 9:59:59,99
setlocal EnabledelayedExpansion
set "at=!%~1!:!%~2!"&if not "!at:~11,1!"==":" (echo [%0] Input Error in %%1: "!%~1!") else if "!at:~-1!"==" " (echo [%0] Input Error in %%2: "!%~2!")
for /F "tokens=1-8 delims=:.," %%a in ("!at: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"
if "%~3" equ "" (set "ap=0!a!" & echo !%~1! !%~2! Elapsed: !a:~0,-2!.!ap:~-2! seconds)
( endlocal & rem return value
if "%~3" neq "" set "%~3=%a%"
)
goto :eof
Result:
Code: Select all
Input F2I FPTOINT FP2INT FP2INT-Alt
' 3/-3' 3000/-3000' 3000/-3000' 3000/-3000' 3000/-3000
' 0/-0' 0/0' 0/0' 0/0' 0/0
' 0.1/-0.1' 100/-100' 100/-100' 100/-100' 100/-100
' 0.6/-0.6' 600/-600' 600/-600' 600/-600' 600/-600
' .1/-.1' 1000/-1000' 100/-100' 100/-100' 100/-100
' .6/-.6' 6000/-6000' 600/-600' 600/-600' 600/-600
' 0.0001/-0.0001' 0/0' 0/0' 0/0' 0/0
' 0.0006/-0.0006' 1/-1' 0/0' 1/-1' 1/-1
' 3.1/-3.1' 3100/-3100' 3100/-3100' 3100/-3100' 3100/-3100
' 3.6/-3.6' 3600/-3600' 3600/-3600' 3600/-3600' 3600/-3600
' 3.0/-3.0' 3000/-3000' 3000/-3000' 3000/-3000' 3000/-3000
' 3.0002/-3.0002' 3000/-3000' 3000/-3000' 3000/-3000' 3000/-3000
' 3.02/-3.02' 3020/-3020' 3020/-3020' 3020/-3020' 3020/-3020
' 3.000/-3.000' 3000/-3000' 3000/-3000' 3000/-3000' 3000/-3000
' 30/-30' 30000/-30000' 30000/-30000' 30000/-30000' 30000/-30000
' 1.083/-1.083' 1083/-1083' 1083/-1083' 1083/-1083' 1083/-1083
' 1.087/-1.087' 1087/-1087' 1087/-1087' 1087/-1087' 1087/-1087
' 1.0837/-1.0837' 1084/-1084' 1083/-1083' 1084/-1084' 1084/-1084
' 0.07/-0.07' 70/-70' 70/-70' 70/-70' 70/-70
' 0.09/-0.09' 90/-90' 90/-90' 90/90' 90/90
' 9/-9' 9000/-9000' 9000/-9000' 9000/-9000' 9000/-9000
' 0.9/-0.9' 900/-900' 900/-900' 900/900' 900/900
' 09.09/-09.09' 90/-90' 9090/-9090' 9090/9090' 9090/9090
Timing F2I...
12:47:52,26 12:48:20,63 Elapsed: 28.37 seconds
Timing FPTOINT...
12:48:20,65 12:48:54,82 Elapsed: 34.17 seconds
Timing FP2INT...
12:48:54,82 12:49:13,05 Elapsed: 18.23 seconds
Timing FP2INT... Alternate input method
12:49:13,07 12:49:30,77 Elapsed: 17.70 seconds
Einstein1696