
批處理實現浮點運算最后由 buyiyang 于 -11-2 18:39批處理不能進行浮點運算是一大憾事,便起念寫一個算法支持浮點,已經寫了加法和乘法,加法比較簡單,不限位數,乘法是通過二進制進行計算的,會有一定誤差,同樣不限位數。分享一下,望指教。更新:添加了除法和求平方根,限制位數。因帖子字數限制,分為兩部分,此為第一部分,三樓為第二部分。
用法:nclick="copycode($('code0'));">復制代碼
- @echo off
- set input=%~1
- if %input%== echo,輸入為空&exit /b
- set input=%input: =%
- if %input%== echo,輸入為空&exit /b
- setlocal enabledelayedexpansion
- for /f tokens=1-2 delims=+-*/ %%i in (%input%) do (
- if not %%j== (set p1=%%i&set p2=%%j) else set p1=%%i
- for /f tokens=1-2 delims=0123456789. %%i in (%input%) do set op=%%i%%j
- if !op!==+ (call :add !p1! !p2!&echo,!add_result!) else if !op!==- (
- echo,減法) else if !op!==* (call :mul !p1! !p2!&echo,!mul_result!) else if !op!==/ (
- call :div !p1! !p2!&echo,!quo_result!) else if !op!== (call :sqrt !p1!&echo,!sqrt_result!) else (echo,操作符錯誤)
- )
- exit /b
- :add
- setlocal
- for /f tokens=1-2 delims=. %%i in (%~1) do (
- set p1_int=%%i
- if %%j== (set /a p1_fd=0) else set p1_fd=%%j
- )
- for /f tokens=1-2 delims=. %%i in (%~2) do (
- set p2_int=%%i
- if %%j== (set /a p2_fd=0) else set p2_fd=%%j
- )
- call :strlen %p1_fd%
- set /a p1_fd_len=%len%
- call :strlen %p2_fd%
- set /a p2_fd_len=%len%
- if %p1_fd_len% geq %p2_fd_len% (set /a fd_len_max=p1_fd_len) else set /a fd_len_max=p2_fd_len
- set zero_fill=
- for /l %%i in (1,1,%fd_len_max%) do set zero_fill=!zero_fill!0
- set p1_fd=%p1_fd%%zero_fill%&set p1_fd=!p1_fd:~0,%fd_len_max%!
- set p2_fd=%p2_fd%%zero_fill%&set p2_fd=!p2_fd:~0,%fd_len_max%!
- set /a carry=0
- set fd_dec=
- for /l %%i in (-1,-1,-%fd_len_max%) do (
- set /a dec_place=!p1_fd:~%%i,1!+!p2_fd:~%%i,1!+!carry!
- if !dec_place! geq 10 (set /a carry=dec_place/10,dec_place=dec_place-10) else set /a carry=0
- set fd_dec=!dec_place!!fd_dec!
- )
- call :strlen %p1_int%
- set /a p1_int_len=%len%
- call :strlen %p2_int%
- set /a p2_int_len=%len%
- if %p1_int_len% geq %p2_int_len% (set /a int_len_max=p1_int_len) else set /a int_len_max=p2_int_len
- set zero_fill=
- for /l %%i in (1,1,%int_len_max%) do set zero_fill=!zero_fill!0
- set p1_int=%zero_fill%%p1_int%&set p1_int=!p1_int:~-%int_len_max%!
- set p2_int=%zero_fill%%p2_int%&set p2_int=!p2_int:~-%int_len_max%!
- set int_dec=
- for /l %%i in (-1,-1,-%int_len_max%) do (
- set /a dec_place=!p1_int:~%%i,1!+!p2_int:~%%i,1!+!carry!
- if !dec_place! geq 10 (set /a carry=dec_place/10,dec_place=dec_place-10) else set /a carry=0
- set int_dec=!dec_place!!int_dec!
- )
- if %carry% gtr 0 set int_dec=%carry%%int_dec%
- if %int_dec% equ 0 (set /a int_dec=0) else for /f tokens=* delims=0 %%i in (%int_dec%) do set int_dec=%%i
- endlocal&set add_result=%int_dec%.%fd_dec%&set int_dec=%int_dec%&set fd_dec=%fd_dec%
- goto :eof
- :mul
- setlocal
- for /f tokens=1-2 delims=. %%i in (%~1) do (
- set p1_int=%%i
- if %%j== (set /a p1_fd=0) else set p1_fd=%%j
- )
- for /f tokens=1-2 delims=. %%i in (%~2) do (
- set p2_int=%%i
- if %%j== (set /a p2_fd=0) else set p2_fd=%%j
- )
- call :int2bin %p1_int%
- set p1_int_bin=%int_bin%
- call :int2bin %p2_int%
- set p2_int_bin=%int_bin%
- call :fd2bin %p1_fd%
- set p1_fd_bin=%fd_bin%
- call :fd2bin %p2_fd%
- set p2_fd_bin=%fd_bin%
- set p1_conbin=%p1_int_bin%%p1_fd_bin%
- set p2_conbin=%p2_int_bin%%p2_fd_bin%
- rem echo,%p1_conbin%
- rem echo,%p2_conbin%
- set /a acc=0
- call :strlen %p1_conbin%
- set /a p1_conbin_len=%len%
- set p2_conbin_shift=%p2_conbin%
- for /l %%i in (-1,-1,-%p1_conbin_len%) do (
- if !p1_conbin:~%%i,1!==1 (call :add_bin !acc! !p2_conbin_shift!)
- set acc=!add_bin_result!
- set p2_conbin_shift=!p2_conbin_shift!0
- )
- set acc=%acc:~0,-32%
- call :strlen %acc%
- set /a acc_len=%len%
- if %acc_len% lss 33 (
- set zero_fill=
- for /l %%i in (1,1,33) do set zero_fill=!zero_fill!0
- set acc=!zero_fill!!acc!
- )
- set acc_fd=%acc:~-32%
- set acc_int=%acc:~0,-32%
- if %acc_int% equ 0 (set /a acc_int=0) else (
- for /f tokens=* delims=0 %%i in (%acc_int%) do set acc_int=%%i
- )
- set acc_int_fd=%acc_int%.%acc_fd%
- rem echo,%acc_int_fd%
- call :bin2dec %acc_int% %acc_fd%
- endlocal&set mul_result=%bin2dec_result%
- goto :eof
- :div
- setlocal
- for /f tokens=1-2 delims=. %%i in (%~1) do (
- set /a p1_int_div=%%i
- if %%j== (set /a p1_fd_div_len=0) else (
- set p1_fd_div=%%j
- call :strlen %%j
- set /a p1_fd_div_len=len
- )
- )
- for /f tokens=* delims=0 %%i in (%p1_fd_div%) do if %%i equ 0 (set /a p1_fd_div=0) else set /a p1_fd_div=%%i
- for /f tokens=1-2 delims=. %%i in (%~2) do (
- call :strlen %%j
- set /a p2_div_fd_len=len
- set p2_div=%%i%%j
- )
- for /f tokens=* delims=0 %%i in (%p2_div%) do set /a p2_div=%%i
- set /a divisor=p2_div,divisor_offset=p2_div_fd_len
- set int_quo=
- set /a int_div_offset=divisor_offset
- for /l %%i in (1,1,32) do (
- if !p1_int_div! lss %divisor% (
- set /a p1_int_div*=10,div_q=0
- set int_quo=!int_quo!!div_q!
- if %%i equ 1 (call :strlen !div_q!&set /a or_len=len)
- ) else (
- set /a div_q=!p1_int_div!/%divisor%,div_mod=!p1_int_div!%%%divisor%
- if %%i equ 1 (call :strlen !div_q!&set /a or_len=len)
- set int_quo=!int_quo!!div_q!
- set p1_int_div=!div_mod!0
- if !div_q! equ 0 goto :int_div_next
- )
- )
- :int_div_next
- set /a int_div_offset+=or_len
- if %int_div_offset% gtr 0 (
- for /f tokens=* delims=0 %%i in (!int_quo:~0,%int_div_offset%!) do if %%i== (set int_quo_int=0) else set int_quo_int=%%i
- set int_quo_fd=!int_quo:~%int_div_offset%!
- ) else (
- for /l %%i in (-1,-1,%int_div_offset%) do set int_quo=0!int_quo!
- set int_quo_int=!int_quo:~0,1!
- set int_quo_fd=!int_quo:~1!
- )
- set int_quo_result=%int_quo_int%.%int_quo_fd%
- set fd_quo=
- set /a dividend=p1_fd_div,fd_div_offset=divisor_offset-p1_fd_div_len-1
- for /l %%i in (1,1,32) do (
- if !dividend! lss %divisor% (
- set /a dividend*=10,div_q=0
- set fd_quo=!fd_quo!!div_q!
- if %%i equ 1 (call :strlen !div_q!&set /a or_len=len)
- ) else (
- set /a div_q=!dividend!/%divisor%,div_mod=!dividend!%%%divisor%
- if %%i equ 1 (call :strlen !div_q!&set /a or_len=len)
- set fd_quo=!fd_quo!!div_q!
- set dividend=!div_mod!0
- if !div_mod! equ 0 goto :fd_div_next
- )
- )
- :fd_div_next
- set /a fd_div_offset+=or_len
- if %fd_div_offset% gtr 0 (set /a fd_div_offset+=1)
- if %fd_div_offset% gtr 0 (
- for /f tokens=* delims=0 %%i in (!fd_quo:~0,%fd_div_offset%!) do if %%i== (set fd_quo_int=0) else set fd_quo_int=%%i
- set fd_quo_fd=!fd_quo:~%fd_div_offset%!
- ) else (
- for /l %%i in (-1,-1,%fd_div_offset%) do set fd_quo=0!fd_quo!
- set fd_quo_int=!fd_quo:~0,1!
- set fd_quo_fd=!fd_quo:~1!
- )
- set fd_quo_result=%fd_quo_int%.%fd_quo_fd%
- call :add %int_quo_result% %fd_quo_result%
- endlocal&set quo_result=%add_result%
- goto :eof
nclick="copycode($('code1'));">復制代碼
- R:>byy.bat 202.3+1.029
- 203.329
- R:>byy.bat 202.3*1.029
- 208.16669997223652899265289306640625
- R:>byy.bat 1102.1102
- 4497.8997651170000000000000000000000
- R:>byy.bat .1102/1102
- 1.8358531760435571687840290381125

