Board logo

标题: [数值计算] [分享]批处理智能计算器 2009-02-26 日更新 [打印本页]

作者: 随风    时间: 2009-2-16 20:12     标题: [分享]批处理智能计算器 2009-02-26 日更新

不知不觉代码越码越长,居然将近500行了、效率也越来越低了。。
还是以附件形式发出来吧、否则谁都看着头晕。
2009-02-26 日更新:
  增加开方功能、
  对小于1的小数输入可省略点前面的0 如 0.6 也可以输入 .6
把功能简单介绍一下。具体的见代码中的说明。
智能批处理计算器
1、计算超大数、小数、负数
2、支持连续算式及三种括弧 如:7+{55-[2*(3+8)-2]+-9*5}--2
3、开方、支持在算式中直接输入 如:6*(5+3x5) 其中 3x5 代表3的5次方。
4、可对文本内的算式进行计算。
5、模仿计算器中的 MR 键、可以临时储存计算结果。
6、开根  还不会,下一步的计划。。。

[ 本帖最后由 随风 于 2009-2-26 19:09 编辑 ]
作者: aabb    时间: 2009-2-16 20:37

希望能写一些引导性的教学贴供我们这些新手学习!!
总是发这些大作,只有自已理解,大多数人不懂!
光是满足一点虚荣心,有点太。。。。。。。。

哎!论坛的高手使终是高手,新手永远是新手,,
两极分化相当严重!!!!!!!希望引起重视
作者: jellyhk    时间: 2009-2-16 21:21

很厉害!
拿来研究下!
作者: BBCC    时间: 2009-2-16 21:24

好像那个方框法除法也适用吧?

还是那个字,乱啊....
作者: 随风    时间: 2009-2-16 21:29

方框法 ? 什么意思,可以说详细点吗?
作者: BBCC    时间: 2009-2-16 21:48

就是类似于竖式的形式,可能有图就比较明显了,但是最近都要上学,可能没时间画...

总之就类似于竖式啦...^^
作者: lhjoanna    时间: 2009-2-17 00:10     标题: 回复 2楼 的帖子

论坛教学区有很多教学贴,只要用心,是肯定能学到不少东西的。完全读懂别人的代码,确实不是件容易的事儿,特别还是比较长、比较复杂的代码。随风也只是贴出自己的辛苦思考出的代码供大家参考、提建议,和虚荣没有多大关系吧!从头开始,耐心的把基础知识打牢,有一天你也会写出很好的代码!
作者: more    时间: 2009-2-18 21:15

对于超大数的除法,本人有一个算法,如下:
    前提是要有一个超大数减法的函数.
    举个例子来说明吧:
    比如用977除以41,
    1.首先取被除数中和除数一样长的位数来减除数,即97-41,余56,给商+1
    2.再用56-41,余15,再给商+1
    3.再用15-41,结果为负,商的第一位即为2
    4.用余数15加上后一位数字(7),再继续减41,即157-41,余116,给商的第二位+1
    5.再用116-41,余75,给商的第二位+1
    6.再用75-41,余34,给商的第二位+1
    7.再用34-41,结果为负,得商的第二位为3
    8.由于被除数已经用完,得最终的结果为:977/41=23
下面是本人做的减法函数和整数除法(未做成函数),目前这个除法计算还不支持浮点运算,希望这两个代码对随风大人有些许帮助...
减法函数:
  1. @echo off
  2. if "%1"=="" goto :hlp
  3. setlocal enableextensions
  4. for %%a in (jie mm mn tm) do (set %%a=0)
  5. for %%a in (baoliu fu last_ans m n no tmp_) do (set %%a=)
  6. set beij=%1
  7. set jian=%2
  8. rem 把被减数首位除0
  9. :cut1
  10. if "%beij:~,1%"=="0" (
  11.   if not "%beij:~1%"=="" (
  12.     if not "%beij:~1,1%"=="." (
  13.       set beij=%beij:~1%
  14.       goto :cut1
  15. )))
  16. rem 把减数首位除0
  17. :cut2
  18. if "%jian:~,1%"=="0" (
  19.   if not "%jian:~1%"=="" (
  20.     if not "%jian:~1,1%"=="." (
  21.       set jian=%jian:~1%
  22.       goto :cut2
  23. )))
  24. rem 判断保留小数的位数
  25. if not "%4"=="" (
  26.   if "%4"=="0" (
  27.     set no=no
  28.   ) else (
  29.     set baoliu=%4
  30.   )
  31. )
  32. rem 把被减数和减数分为整数和小数两个部分
  33. for /f "tokens=1,2 delims=." %%a in ("%beij%") do (
  34.   set "stral=%%a"&set "strar=%%b"
  35. )
  36. for /f "tokens=1,2 delims=." %%a in ("%jian%") do (
  37.   set "strbl=%%a"&set "strbr=%%b"
  38. )
  39. rem 如果不保留小数,则跳过对小数部分的计算
  40. if defined no (
  41.   set stra=%stral%
  42.   set strb=%strbl%
  43.   goto :agn1
  44. )
  45. rem 如果没有小数,则跳过对小数部分的计算
  46. if "%strar%"=="" (
  47.   if "%strbr%"=="" (
  48.     set no=no
  49.     set stra=%stral%
  50.     set strb=%strbl%
  51.     goto :agn1
  52.   )
  53. )
  54. rem 计算被减数小数部分的位数
  55. set "tmp_=%strar%"
  56. :cnt1
  57. if defined tmp_ (
  58.   set /a mm+=1
  59.   set tmp_=%tmp_:~1%
  60.   goto :cnt1
  61. )
  62. set "bu0=%mm%"
  63. rem 计算减数小数部分的位数
  64. set "tmp_=%strbr%"
  65. :cnt2
  66. if defined tmp_ (
  67.   set /a mn+=1
  68.   set tmp_=%tmp_:~1%
  69.   goto :cnt2
  70. )
  71. if %mn% gtr %mm% set bu0=%mn%
  72. rem 将两个减数的小数部分对齐
  73. for /l %%a in (1 1 %bu0%) do (call set bu=%%bu%%0)
  74. set strar=%strar%%bu%
  75. set strbr=%strbr%%bu%
  76. call set strar=%%strar:~,%bu0%%%
  77. call set strbr=%%strbr:~,%bu0%%%
  78. set "bu="
  79. rem 如果定义小数位数,则取定义的位数
  80. if defined baoliu (
  81.   for /l %%a in (1 1 %baoliu%) do (call set bu=%%bu%%0)
  82.   call set strar=%strar%%%bu%%
  83.   call set strbr=%strbr%%%bu%%
  84.   call set stra=%stral%%%strar:~,%baoliu%%%
  85.   call set strb=%strbl%%%strbr:~,%baoliu%%%
  86. ) else (
  87.   set stra=%stral%%strar%
  88.   set strb=%strbl%%strbr%
  89. )
  90. rem 计算被减数整数部分的位数
  91. :agn1
  92. set /a m+=1
  93. if not "%stral:~1%"=="" (set stral=%stral:~1%&goto :agn1)
  94. rem 计算减数整数部分的位数
  95. :agn2
  96. set /a n+=1
  97. if not "%strbl:~1%"=="" (set strbl=%strbl:~1%&goto :agn2)
  98. rem 判断正负
  99. if %n% gtr %m% (
  100.   set fu=fu
  101.   set "beijshu=%strb%"
  102.   set "jianshu=%stra%"
  103. ) else (
  104.   if "%n%"=="%m%" (
  105.     set tmp1=%stra%
  106.     set tmp2=%strb%
  107.     goto :pk
  108.   ) else (
  109.     set "beijshu=%stra%"
  110.     set "jianshu=%strb%"
  111.   )
  112. )
  113. rem 计算
  114. :agn
  115. set /a sth=%beijshu:~-1%-%jianshu:~-1%-%jie%
  116. if %sth% lss 0 (
  117.   set jie=1
  118.   set /a sth+=10
  119. ) else (
  120.   set jie=0
  121. )
  122. set last_ans=%sth%%last_ans%
  123. if not "%beijshu:~,-1%"=="" (
  124.   if not "%jianshu:~,-1%"=="" (
  125.     set "beijshu=%beijshu:~,-1%"&set "jianshu=%jianshu:~,-1%"&goto :agn
  126.   ) else (
  127.     set "beijshu=%beijshu:~,-1%"&set "jianshu=0"&goto :agn
  128.   )
  129. )
  130. rem 不保留小数的除0以及正负数处理
  131. :cut0
  132. if defined no (
  133.   if not "%last_ans:~,1%"=="0" (
  134.     if not defined fu (
  135.       endlocal&set %3=%last_ans%&goto :eof
  136.     ) else (
  137.       endlocal&set %3=-%last_ans%&goto :eof
  138.       )
  139.   ) else (
  140.     set last_ans=%last_ans:~1%
  141.     goto :cut0
  142.   )
  143. )
  144. rem 对小数点进行定位
  145. if defined baoliu (
  146.   call set last_ans=%%last_ans:~,-%baoliu%%%.%%last_ans:~-%baoliu%%%
  147. ) else (
  148.   if bu0 gtr 0 (
  149.     call set last_ans=%%last_ans:~,-%bu0%%%.%%last_ans:~-%bu0%%%
  150.   )
  151. )
  152. rem 首位除0处理
  153. :cut_
  154. if "%last_ans:~,1%"=="0" (
  155.   if not "%last_ans:~1,1%"=="." (
  156.     set last_ans=%last_ans:~1%
  157.     goto :cut_
  158.   )
  159. )
  160. rem 正负处理
  161. if defined fu (
  162.   set last_ans=-%last_ans%
  163. )
  164. rem 退出脚本
  165. endlocal&set %3=%last_ans%&goto :eof
  166. rem 判断相同位数的大小
  167. :pk
  168. if %tmp1:~,1% gtr %tmp2:~,1% (
  169.   set beijshu=%stra%
  170.   set jianshu=%strb%
  171.   goto :agn
  172. ) else (
  173.   if %tmp2:~,1% gtr %tmp1:~,1% (
  174.     set fu=fu
  175.     set beijshu=%strb%
  176.     set jianshu=%stra%
  177.     goto :agn
  178.   ) else (
  179.     if not "%tmp1:~1%"=="" (
  180.       set tmp1=%tmp1:~1%
  181.       set tmp2=%tmp2:~1%
  182.       goto :pk
  183.     ) else (
  184.       endlocal&set %3=0&goto :eof
  185.     )
  186.   )
  187. )
  188. :hlp
  189. color 1f
  190. echo.&echo  使用方法:
  191. echo.&echo  1.把本批处理脚本命名为 jianfa.bat 复制到系统目录里
  192. echo.&echo  2.不带参数运行本批处理脚本显示此帮助信息
  193. echo.&echo  3.格式: call jianfa.bat 参数1 参数2 参数3 [参数4]
  194. echo.&echo    参数1     为被减数
  195. echo.&echo    参数2     为减数
  196. echo.&echo    参数3     为变量名
  197. echo.&echo    [参数4]   可选参数,为保留小数位数,如不选则保留原有小数.
  198. echo.&echo  4.例: call jianfa.bat 100 123.456789 ans 2
  199. echo.&echo    意思为给变量 ans 赋值,其值等于 100 减去 123.456789 的差,
  200. echo.&echo    并保留两位小数,结果为: -23.45
  201. echo.&set/p=   按任意键退出...nul&color&goto :eof
复制代码

整数除法:
  1. @echo off
  2. Setlocal Enabledelayedexpansion
  3. :bgn
  4. set "last_ans="
  5. for %%a in (fu m m1 n1) do (set %%a=0)
  6. set /p beichu=被除数:
  7. if "%beichu:~,1%"=="-" (
  8.   set /a fu+=1
  9.   set beichu=%beichu:~1%
  10. ) else (
  11.   if "%beichu:~,1%"=="+" (set beichu=%beichu:~1%)
  12. )
  13. set /p chu=除  数:
  14. if "%chu:~,1%"=="-" (
  15.   set /a fu+=1
  16.   set chu=%chu:~1%
  17. ) else (
  18.   if "%chu:~,1%"=="+" (set chu=%chu:~1%)
  19. )
  20. rem 取除数的整数部分
  21. for /f "delims=." %%a in ("%chu%") do (set chu=%%a)
  22. :cut
  23. if "%chu:~,1%"=="0" (
  24.   if not "%chu:~1%"=="" (set chu=%chu:~1%&goto :cut)
  25. )
  26. if "%chu%"=="0" (echo 除数不能为0&goto :bgn)
  27. set strc=%chu%
  28. rem 取被除数的整数部分
  29. for /f "delims=." %%a in ("%beichu%") do (set beichu=%%a)
  30. set strb=%beichu%
  31. rem 计算被除数的长度
  32. :cnt1
  33. set /a m1+=1
  34. if not "%strb:~1%"=="" (set strb=%strb:~1%&goto :cnt1)
  35. rem 计算除数的长度
  36. :cnt2
  37. set /a n1+=1
  38. if not "%strc:~1%"=="" (set strc=%strc:~1%&goto :cnt2)
  39. if %n1% gtr %m1% (echo 商  是:0&echo.&goto :bgn)
  40. set var=!beichu:~,%n1%!
  41. :agn
  42. call jianfa.bat %var% %chu% rslt 0
  43. if "%rslt:~,1%"=="-" (
  44.   set last_ans=%last_ans%%m%
  45.   set m=0
  46.   if not "!beichu:~%n1%,1!"=="" (
  47.     set var=%var%!beichu:~%n1%,1!
  48.     set /a n1+=1
  49.     goto :agn
  50.   ) else (
  51.     goto :cut0
  52.   )
  53. ) else (
  54.   set /a m+=1
  55.   set var=%rslt%
  56.   goto :agn
  57. )
  58. rem 首位除0处理
  59. :cut0
  60. if "%last_ans:~,1%"=="0" (
  61.   if not "%last_ans:~1%"=="" (
  62.     set last_ans=%last_ans:~1%
  63.     goto :cut0
  64.   )
  65. )
  66. rem 判断正负
  67. if "%fu%"=="1" (set last_ans=-%last_ans%)
  68. echo 商  是:%last_ans%
  69. echo.&goto :bgn
复制代码

作者: gfwlxx    时间: 2009-2-19 09:09

1-2-3 = -22

请输入算式:
作者: more    时间: 2009-2-21 10:47

回9楼,其实我也这么弄过,不过看了顶楼中的描述即可看出这个代码只能处理两个数的四则运算...
    在我的想像中,一个计算器应该是智能的,我想这也是大家追求的:
    比如我要做一个批处理来计算一个圆柱形水桶的容积,而且还可以重复计算,用来对比各种数据以调整这个水桶的形状
@echo off
set pai=3.14152926
:bgn
set /p ban=半径(厘米):
set /p gao=高(厘米):
call 计算.bat %pai%*%ban%*%ban%*%gao%/1000 var 2
rem 这句的意思是给var赋值,它的值是以输入的数据来计算水桶的容积,并保留两位小数
echo 可以装 %var% 公斤水
echo.&goto :bgn

而我现在只能做到加减乘除各一个函数,无法把它们集成一个,因为要智能的判断一个算式太难了...
希望随风超版能考虑考虑...
其实我更希望更多的人参与进来共同完成这个超级计算器...
作者: xiaoruiado    时间: 2009-2-21 17:00

额,貌似很麻烦啊......................
作者: 随风    时间: 2009-2-21 19:12     标题: 回复 10楼 的帖子

其实解决了小数问题,你说的应该就不太难了,又是一大堆的体力活而以,并且对效率将又是一大挑战。
作者: zjw767676    时间: 2009-2-23 20:42

很好,很强大!假如能开方和开根就完美了!!
输入0.23*9=2.07
输入.23*9=207小数点前面的0不能省略!
作者: xy506    时间: 2009-2-23 23:24

发现一个小BUG:0/123+1=
不存在··
这个是一个简单的极限运算·这个也应该算是功能不完善吧。
作者: 523066680    时间: 2009-2-26 17:08

占个位子~   也想试除法,

abcde
93212 / 33
        abcde
预定00000           0
00000    <abcde    ab+33                   1
33000    <abcde    ab+33                   2   
66000    <abcde    ab+33                   3
99000    >abcde     所以首位选3  现在预定66000
                          第2号数初始为0
66000   <abcde    bc+33           1
69300   <abcde    bc+33           2
72600   <abcde    bc+33           3
.....

主要用自带的加法完成。判断时用0冲当,就不用减法了……


听了flyinspace 一席言,又明白很多东西了~   。不过,这个回贴还是留着吧。

[ 本帖最后由 523066680 于 2009-2-27 17:25 编辑 ]
作者: more    时间: 2009-2-28 14:13

感觉随风大人的除法比我的快多了,可以分享除法的算法吗?谢谢!!!
作者: defanive    时间: 2009-2-28 14:31

直接调用VBS不就好了么。。。

收录这些函数。。。
作者: Batcher    时间: 2009-2-28 15:18     标题: 回复 17楼 的帖子

因为有些场合不能用VBS,如果要说调用的话,调用VBS干吗,有现成的第三方工具可以呢。
具体情况,具体分析。
作者: 523066680    时间: 2009-2-28 15:51

对了  flyinspace 说  计算机里面的算法在过了100位以后速度会更快.

而用类似笔算的算发 过70位就会吃力,  所以我就没打算写下去了


对于vbs ,  俺们探究的是思路 ,探究最基础的思路.

而且vbs也不给出所有位,
=======================================================


对随风的作品 我有一新建议,    -----   添加功能:   用xxx字符代替上次计算的答案.
作者: more    时间: 2009-3-9 16:45

强烈建议随风把这个做成函数以便调用,谢谢!!!
作者: Demon    时间: 2011-6-1 22:26

这个要膜拜一下
作者: sds    时间: 2023-2-10 20:11

厉害,话说怎么计算小数的
作者: yyz219    时间: 2023-2-11 17:10

不知不觉代码越码越长,居然将近500行了、效率也越来越低了。。
还是以附件形式发出来吧、否则谁都看着头晕 ...
随风 发表于 2009-2-16 20:12



     感谢分享




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2