【批处理】解一元二次方程 更新2 保留5位小数
本帖最后由 套路 于 2018-9-21 18:38 编辑2018/6/14 更新1:对显示进行优化,可显示带入求根公式的过程。
2018/6/22 更新2:修复了大数字进行运算误差大的BUG,并可以保留到5位小数。
批处理来计算一元二次方程 看起来很简单
不就是利用这个公式https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=1325611025,884420251&fm=58
但是,批处理不像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位小数,感觉不多不少,应该还可以进行计算
试验了一下,还真的可以,但是我试验的时候有一些乱码。
感觉像是中文的字符出现了乱码 溯影 发表于 2018-6-14 16:52
试验了一下,还真的可以,但是我试验的时候有一些乱码。
感觉像是中文的字符出现了乱码 ...
应该是保存时不是ANSI编码吧 套路 发表于 2018-6-14 17:33
应该是保存时不是ANSI编码吧
我用notepad++保存的,保存的编码是utf-8时候汉字是正常的,但是别的编码例如ansi,gb2312等都是中文乱码,但是运行的时候即使是utf-8也是中文显示乱码。 套路 发表于 2018-6-14 17:33
应该是保存时不是ANSI编码吧
哦哦,感谢指点,我刚百度了一下,小弟我在试一下。 可以了,另存为,然后编码是ansi就可以了。:lol
学习了 谢谢大佬讲解
页:
[1]