- UID
- 3517
- 精华
- 积分
- 959
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
本帖最后由 套路 于 2018-9-21 18:38 编辑
2018/6/14 更新1:对显示进行优化,可显示带入求根公式的过程。
2018/6/22 更新2:修复了大数字进行运算误差大的BUG,并可以保留到5位小数。
批处理来计算一元二次方程 看起来很简单
不就是利用这个公式
但是,批处理不像C语言,VB等等一样能计算小数和平方根!!!
所以只能用加减乘除来计算平方根的近似值,再将小数点当成字符插入。
- @echo off
- setlocal enabledelayedexpansion
- title 解一元二次方程
- :menu
- set a=
- set b=
- set c=
- cls
- echo aX^^2+bX+c=0 (a≠0)
- echo 注:因为批处理不支持小数运算,a,b,c的值请化为整数
- set /p a=a^=
- set /p b=b^=
- set /p c=c^=
- ::判断是否为数字
- set /a a1=a+0
- set /a b1=b+0
- set /a c1=c+0
- if not "%a1%"=="%a%" (goto no1)
- if not "%b1%"=="%b%" (goto no1)
- if not "%c1%"=="%c%" (goto no1)
- ::对显示进行美化
- if %b% GTR 0 (set b2=+%b%) else (set b2=%b%)
- if %c% GTR 0 (set c2=+%c%) else (set c2=%c%)
- if %a%==0 (set a2=) else (set a2=%a%)
- if %a%==1 (set a2=)
- if %a%==-1 (set a2=-)
- if %b%==1 (set b2=+)
- if %b%==-1 (set b2=-)
- if %b%==0 (set b3=) else (set b3=%b2%X)
- if %c%==0 (set c2=)
- ::判断根的情况
- If "%a%"=="0" goto no
- set /a h=%b%*%b%-4*%a%*%c%
- If %h% lss 0 goto no2
- If "%h%"=="0" goto yes2
- If %h% GTR 0 goto yes
-
- :no
- echo.
- echo 错误:
- echo a=0,不是一元二次方程
- pause
- goto menu
-
- :no1
- echo.
- echo 错误:
- echo a,b,c只能为数字且不能超过批处理支持运算的最大的数2147483647!
- echo 如果没有此项,请用0表示
- pause
- goto menu
-
- :no2
- echo.
- echo 错误:
- echo △=%h%^<0
- echo 该方程无实数根
- pause
- goto menu
-
- :yes
- ::计算判别式的平方根
- set /a s=h
- set /a w=5
- if defined W (for /l %%i in (1 1 %W%) do set "s=!s!00") else set W=0
- set p=!s!&set /a len=N=0
- for %%i in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do IF "!p:~%%i!" NEQ "" set/a len+=%%i&set "p=!p:~%%i!"
- set /a "N-=~(len%%2)"
- set M=!s:~,%N%!
- for /l %%i in (1 1 9) do set/a Mx=%%i*%%i&if !Mx! leq !M! set/a "i=%%i,j=100+M-Mx"
- set /a "len-=1,Len_i=_N=i/5+1,p=i*20"
- set j=!j:~-%_N%!&set p=0!p!&set kl=0000000
- set /a _N=8-_N
- for /l %%i in (%N% 2 !len!) do (
- set "j=!j!!s:~%%i,2!"
- if "!j:0=!" neq "" (
- set /a Ln_i=Len_i+=2
- if "!p!" lss "!j!" (
- set d=Z&set in=!kl!!P!&set /a Ln_i+=7
- for /l %%j in (9 -1 2) do (
- if "!d!" gtr "!j!" (
- set "x=%%j"
- set d=&set /a "y=x*x"
- for /l %%k in (8 8 !Ln_i!) do (
- set /a "y=1!in:~-%%k,8!*%%j+y"
- set d=!y:~-8!!d!&set /a "y=!y:~,-8!-%%j"
- )
- set d=!y!!d!
- for %%k in (!Len_i!) do set "d=!d:~-%%k!"
- )
- )
- if "!d!" gtr "!j!" (set d=!in!&set x=1&set y=1) else set d=!kl!!d!&set y=0
- set j=!kl!!j!&set "t="
- for /l %%j in (8 8 !Ln_i!) do (
- set /a "y=3!j:~-%%j,8!-1!d:~-%%j,8!-!y:~,1!%%2"
- set "t=!y:~1!!t!"
- )
- for %%j in (!Len_i!) do set "j=!t:~-%%j!"
- set "j=!j:~1!" ) else set "x=0"
- set /a "Len_i-=1"
- if "!x!" neq "0" (
- if "!x!" geq "5" (
- set p=&set y=0&set "in=!kl!!i!!x!"
- set /a "Ln_i=Len_i+_N"
- for /l %%j in (8 8 !Ln_i!) do (
- set /a "y=1!in:~-%%j,8!*2+!y:~,1!%%2"
- set p=!y:~1!!p!
- )
- set /a "y=!y:~,1!%%2"
- for %%j in (!Len_i!) do set "p=!y:1=01!!p:~-%%j!0"
- ) else set /a t=x*2&set "p=!p:~,-1!!t!0"
- ) else set p=!p!0&set "j=!j:~1!"
- ) else set j=!j:~1!&set p=!p!0&set /a "Len_i+=1,x=0"
- set i=!i!!x!
- )
- ::计算X1,X2的100倍
- :xs
- set /a o=(-%b%*100000+%i%)/(%a%*2)
- set /a r=(-%b%*100000-%i%)/(%a%*2)
- ::如果不是5位数,前几位补零
- set /a o1=o
- if %o% LSS 0 (
- set /a o=-1*o
- )
- if %o% LSS 10 (
- set o=00000%o%
- )
- if %o% LSS 100 (
- if %o% GEQ 10 (
- set o=0000%o%
- ))
- if %o% LSS 1000 (
- if %o% GEQ 100 (
- set o=000%o%
- ))
- if %o% LSS 10000 (
- if %o% GEQ 1000 (
- set o=00%o%
- ))
- if %o% LSS 100000 (
- if %o% GEQ 10000 (
- set o=0%o%
- ))
- if %o% GEQ 100000 (
- set o=%o%
- )
- if %o1% LSS 0 (
- set o=-%o%
- )
- set /a r1=r
- if %r% LSS 0 (
- set /a r=-1*r
- )
- if %r% LSS 10 (
- set r=00000%r%
- )
- if %r% LSS 100 (
- if %r% GEQ 10 (
- set r=0000%r%
- ))
- if %r% LSS 1000 (
- if %r% GEQ 100 (
- set r=000%r%
- ))
- if %r% LSS 10000 (
- if %r% GEQ 1000 (
- set r=00%r%
- ))
- if %r% LSS 100000 (
- if %r% GEQ 10000 (
- set r=0%r%
- ))
- if %r% GEQ 100000 (
- set r=%r%
- )
- if %r1% LSS 0 (
- set r=-%r%
- )
- ::在倒数第五位前加上“.”
- set /a n=-b
- set /a m=2*a
- for /f "tokens=* delims=." %%o in ("!o:~,-%W%!.!o:~-%W%!") do set x1=%%o
- for /f "tokens=* delims=." %%r in ("!r:~,-%W%!.!r:~-%W%!") do set x2=%%r
- ::去掉保留小数的0
- :ctx1
- if "%x1:~-1%"=="0" (
- set cx1=,-1
- if "%x1:~-2%"=="00" (
- set cx1=,-2
- if "%x1:~-3%"=="000" (
- set cx1=,-3
- if "%x1:~-4%"=="0000" (
- set cx1=,-4
- if "%x1:~-5%"=="00000" (
- set cx1=,-6
- ) else (goto ctx2)
- ) else (goto ctx2)
- ) else (goto ctx2)
- ) else (goto ctx2)
- ) else (goto ctx2)
- :ctx2
- if "%x2:~-1%"=="0" (
- set cx2=,-1
- if "%x2:~-2%"=="00" (
- set cx2=,-2
- if "%x2:~-3%"=="000" (
- set cx2=,-3
- if "%x2:~-4%"=="0000" (
- set cx2=,-4
- if "%x2:~-5%"=="00000" (
- set cx2=,-6
- ) else (goto next)
- ) else (goto next)
- ) else (goto next)
- ) else (goto next)
- ) else (goto next)
- :next
- cls
- echo %a2%X^^2%b3%%c2%=0
- echo △=%h%
- echo X1=(%n%+√%h%)/%m%=!x1:~%cx1%!
- echo X2=(%n%-√%h%)/%m%=!x2:~%cx2%!
- pause
- goto menu
-
- :yes2
- set /a x=(-%b%)/(%a%*2)
- set /a n=-b
- set /a m=2*a
- cls
- echo %a2%X^^2%b3%%c2%=0
- echo △=%h%
- echo X1=X2=(%n%+0)/%m%=%x%
- pause
- goto menu
复制代码
其实可以保留更多位小数
因为批处理不支持小数,只能将小数点当成字符插入
而批处理支持运算的最大的数为2147483647,超过这个数就会变成负数
保留跟多位小数可能会导致计算失败
所以我保留了5位小数,感觉不多不少,应该还可以进行计算
|
|