找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3752|回复: 6

【批处理】解一元二次方程 更新2 保留5位小数

[复制链接]
5 个宅币 回复本帖可获得 1 个宅币奖励! 每人限 1 次(中奖概率 10%)
发表于 2018-6-14 12:52:22 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 套路 于 2018-9-21 18:38 编辑

2018/6/14 更新1:对显示进行优化,可显示带入求根公式的过程。
2018/6/22 更新2:修复了大数字进行运算误差大的BUG,并可以保留到5位小数。

批处理来计算一元二次方程 看起来很简单
不就是利用这个公式
但是,批处理不像C语言,VB等等一样能计算小数和平方根!!!
所以只能用加减乘除来计算平方根的近似值,再将小数点当成字符插入。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. title 解一元二次方程
  4. :menu
  5. set a=
  6. set b=
  7. set c=
  8. cls
  9. echo aX^^2+bX+c=0 (a≠0)
  10. echo 注:因为批处理不支持小数运算,a,b,c的值请化为整数
  11. set /p a=a^=
  12. set /p b=b^=
  13. set /p c=c^=
  14. ::判断是否为数字
  15. set /a a1=a+0
  16. set /a b1=b+0
  17. set /a c1=c+0
  18. if not "%a1%"=="%a%" (goto no1)
  19. if not "%b1%"=="%b%" (goto no1)
  20. if not "%c1%"=="%c%" (goto no1)
  21. ::对显示进行美化
  22. if %b% GTR 0 (set b2=+%b%) else (set b2=%b%)
  23. if %c% GTR 0 (set c2=+%c%) else (set c2=%c%)
  24. if %a%==0 (set a2=) else (set a2=%a%)
  25. if %a%==1 (set a2=)
  26. if %a%==-1 (set a2=-)
  27. if %b%==1 (set b2=+)
  28. if %b%==-1 (set b2=-)
  29. if %b%==0 (set b3=) else (set b3=%b2%X)
  30. if %c%==0 (set c2=)
  31. ::判断根的情况
  32. If "%a%"=="0" goto no
  33. set /a h=%b%*%b%-4*%a%*%c%
  34. If %h% lss 0 goto no2
  35. If "%h%"=="0" goto yes2
  36. If %h% GTR 0 goto yes

  37. :no
  38. echo.
  39. echo 错误:
  40. echo a=0,不是一元二次方程
  41. pause
  42. goto menu
  43.   
  44. :no1
  45. echo.
  46. echo 错误:
  47. echo a,b,c只能为数字且不能超过批处理支持运算的最大的数2147483647!
  48. echo 如果没有此项,请用0表示
  49. pause
  50. goto menu
  51.   
  52. :no2
  53. echo.
  54. echo 错误:
  55. echo △=%h%^<0
  56. echo 该方程无实数根
  57. pause
  58. goto menu

  59. :yes
  60. ::计算判别式的平方根
  61. set /a s=h
  62. set /a w=5
  63. if defined W (for /l %%i in (1 1 %W%) do set "s=!s!00") else set W=0
  64. set p=!s!&set /a len=N=0
  65. 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!"
  66. set /a "N-=~(len%%2)"
  67. set M=!s:~,%N%!
  68. 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"
  69. set /a "len-=1,Len_i=_N=i/5+1,p=i*20"
  70. set j=!j:~-%_N%!&set p=0!p!&set kl=0000000
  71. set /a _N=8-_N
  72. for /l %%i in (%N% 2 !len!) do (
  73. set "j=!j!!s:~%%i,2!"
  74. if "!j:0=!" neq "" (
  75. set /a Ln_i=Len_i+=2
  76. if "!p!" lss "!j!" (
  77. set d=Z&set in=!kl!!P!&set /a Ln_i+=7
  78. for /l %%j in (9 -1 2) do (
  79. if "!d!" gtr "!j!" (
  80. set "x=%%j"
  81. set d=&set /a "y=x*x"
  82. for /l %%k in (8 8 !Ln_i!) do (
  83. set /a "y=1!in:~-%%k,8!*%%j+y"
  84. set d=!y:~-8!!d!&set /a "y=!y:~,-8!-%%j"
  85. )
  86. set d=!y!!d!
  87. for %%k in (!Len_i!) do set "d=!d:~-%%k!"
  88. )
  89. )
  90. if "!d!" gtr "!j!" (set d=!in!&set x=1&set y=1) else set d=!kl!!d!&set y=0
  91. set j=!kl!!j!&set "t="
  92. for /l %%j in (8 8 !Ln_i!) do (
  93. set /a "y=3!j:~-%%j,8!-1!d:~-%%j,8!-!y:~,1!%%2"
  94. set "t=!y:~1!!t!"
  95. )
  96. for %%j in (!Len_i!) do set "j=!t:~-%%j!"
  97. set "j=!j:~1!" ) else set "x=0"
  98. set /a "Len_i-=1"
  99. if "!x!" neq "0" (
  100. if "!x!" geq "5" (
  101. set p=&set y=0&set "in=!kl!!i!!x!"
  102. set /a "Ln_i=Len_i+_N"
  103. for /l %%j in (8 8 !Ln_i!) do (
  104. set /a "y=1!in:~-%%j,8!*2+!y:~,1!%%2"
  105. set p=!y:~1!!p!
  106. )
  107. set /a "y=!y:~,1!%%2"
  108. for %%j in (!Len_i!) do set "p=!y:1=01!!p:~-%%j!0"
  109. ) else set /a t=x*2&set "p=!p:~,-1!!t!0"
  110. ) else set p=!p!0&set "j=!j:~1!"
  111. ) else set j=!j:~1!&set p=!p!0&set /a "Len_i+=1,x=0"
  112. set i=!i!!x!
  113. )
  114. ::计算X1,X2的100倍
  115. :xs
  116. set /a o=(-%b%*100000+%i%)/(%a%*2)
  117. set /a r=(-%b%*100000-%i%)/(%a%*2)
  118. ::如果不是5位数,前几位补零
  119. set /a o1=o
  120. if %o% LSS 0 (
  121. set /a o=-1*o
  122. )
  123. if %o% LSS 10 (
  124. set o=00000%o%
  125. )
  126. if %o% LSS 100 (
  127. if %o% GEQ 10 (
  128. set o=0000%o%
  129. ))
  130. if %o% LSS 1000 (
  131. if %o% GEQ 100 (
  132. set o=000%o%
  133. ))
  134. if %o% LSS 10000 (
  135. if %o% GEQ 1000 (
  136. set o=00%o%
  137. ))
  138. if %o% LSS 100000 (
  139. if %o% GEQ 10000 (
  140. set o=0%o%
  141. ))
  142. if %o% GEQ 100000 (
  143. set o=%o%
  144. )
  145. if %o1% LSS 0 (
  146. set o=-%o%
  147. )
  148. set /a r1=r
  149. if %r% LSS 0 (
  150. set /a r=-1*r
  151. )
  152. if %r% LSS 10 (
  153. set r=00000%r%
  154. )
  155. if %r% LSS 100 (
  156. if %r% GEQ 10 (
  157. set r=0000%r%
  158. ))
  159. if %r% LSS 1000 (
  160. if %r% GEQ 100 (
  161. set r=000%r%
  162. ))
  163. if %r% LSS 10000 (
  164. if %r% GEQ 1000 (
  165. set r=00%r%
  166. ))
  167. if %r% LSS 100000 (
  168. if %r% GEQ 10000 (
  169. set r=0%r%
  170. ))
  171. if %r% GEQ 100000 (
  172. set r=%r%
  173. )
  174. if %r1% LSS 0 (
  175. set r=-%r%
  176. )
  177. ::在倒数第五位前加上“.”
  178. set /a n=-b
  179. set /a m=2*a
  180. for /f "tokens=* delims=." %%o in ("!o:~,-%W%!.!o:~-%W%!") do set x1=%%o
  181. for /f "tokens=* delims=." %%r in ("!r:~,-%W%!.!r:~-%W%!") do set x2=%%r
  182. ::去掉保留小数的0
  183. :ctx1
  184. if "%x1:~-1%"=="0" (
  185. set cx1=,-1
  186. if "%x1:~-2%"=="00" (
  187. set cx1=,-2
  188. if "%x1:~-3%"=="000" (
  189. set cx1=,-3
  190. if "%x1:~-4%"=="0000" (
  191. set cx1=,-4
  192. if "%x1:~-5%"=="00000" (
  193. set cx1=,-6
  194. ) else (goto ctx2)
  195. ) else (goto ctx2)
  196. ) else (goto ctx2)
  197. ) else (goto ctx2)
  198. ) else (goto ctx2)
  199. :ctx2
  200. if "%x2:~-1%"=="0" (
  201. set cx2=,-1
  202. if "%x2:~-2%"=="00" (
  203. set cx2=,-2
  204. if "%x2:~-3%"=="000" (
  205. set cx2=,-3
  206. if "%x2:~-4%"=="0000" (
  207. set cx2=,-4
  208. if "%x2:~-5%"=="00000" (
  209. set cx2=,-6
  210. ) else (goto next)
  211. ) else (goto next)
  212. ) else (goto next)
  213. ) else (goto next)
  214. ) else (goto next)
  215. :next
  216. cls
  217. echo %a2%X^^2%b3%%c2%=0
  218. echo △=%h%
  219. echo X1=(%n%+√%h%)/%m%=!x1:~%cx1%!
  220. echo X2=(%n%-√%h%)/%m%=!x2:~%cx2%!
  221. pause
  222. goto menu

  223. :yes2
  224. set /a x=(-%b%)/(%a%*2)
  225. set /a n=-b
  226. set /a m=2*a
  227. cls
  228. echo %a2%X^^2%b3%%c2%=0
  229. echo △=%h%
  230. echo X1=X2=(%n%+0)/%m%=%x%
  231. pause
  232. goto menu
复制代码

其实可以保留更多位小数
因为批处理不支持小数,只能将小数点当成字符插入
而批处理支持运算的最大的数为2147483647,超过这个数就会变成负数
保留跟多位小数可能会导致计算失败
所以我保留了5位小数,感觉不多不少,应该还可以进行计算
回复

使用道具 举报

发表于 2018-6-14 16:52:25 | 显示全部楼层
试验了一下,还真的可以,但是我试验的时候有一些乱码。
感觉像是中文的字符出现了乱码
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2018-6-14 17:33:24 | 显示全部楼层
溯影 发表于 2018-6-14 16:52
试验了一下,还真的可以,但是我试验的时候有一些乱码。
感觉像是中文的字符出现了乱码 ...

应该是保存时不是ANSI编码吧
回复 赞! 靠!

使用道具 举报

发表于 2018-6-14 21:13:34 | 显示全部楼层
套路 发表于 2018-6-14 17:33
应该是保存时不是ANSI编码吧

我用notepad++保存的,保存的编码是utf-8时候汉字是正常的,但是别的编码例如ansi,gb2312等都是中文乱码,但是运行的时候即使是utf-8也是中文显示乱码。
回复 赞! 靠!

使用道具 举报

发表于 2018-6-14 21:14:45 | 显示全部楼层
套路 发表于 2018-6-14 17:33
应该是保存时不是ANSI编码吧

哦哦,感谢指点,我刚百度了一下,小弟我在试一下。
回复 赞! 靠!

使用道具 举报

发表于 2018-6-14 21:17:50 | 显示全部楼层
可以了,另存为,然后编码是ansi就可以了。
学习了
回复 赞! 靠!

使用道具 举报

发表于 2018-8-6 08:51:02 | 显示全部楼层
谢谢大佬讲解
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 02:42 , Processed in 0.036812 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表