[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
本帖最后由 happy886rr 于 2016-4-5 14:59 编辑

回复 1# 随风
我也写了个批处理大数浮点乘法,任意位,任意小数乘法均可以计算。
全精度浮点乘,批处理的各种特殊性全部考虑,计算效率极佳。
只受限于批处理的输入,批处理最多允许输入一千多位。但是,程序可以扩展。稍加改造即可用多个字符串来存储输入。这样理论上是无限制的。当然最大限制是6300位大数,源于批处理的2的31次方限制。
  1. @echo off&mode con cols=58 lines=38
  2. :MAIN
  3. cls
  4. echo 浮点乘表达式^(乘号用*表示^)
  5. set /p Express=-^>
  6. setlocal enabledelayedexpansion
  7. REM 浮点计数
  8. for /f "tokens=1,2 delims=*" %%a in ("!Express!") do (
  9. set A=%%a&set A=!A: =!
  10. set B=%%b&set B=!B: =!
  11. )
  12. for /f "tokens=1,2 delims=." %%a in ("!A!") do (
  13. set A1=%%a&set A=!A1!%%b
  14. if "%%b"=="" (set PA=0) else (
  15. set A2=%%b
  16. for %%i in (512 256 128 64 32 16 8 4 2 1) do (
  17.     if not "!A2:~%%i!"=="" (
  18. set/a PA+=%%i
  19. set "A2=!A2:~%%i!"
  20. )
  21. )
  22. if "!A2:~1!"=="" (set/a PA+=1)
  23. )
  24. )
  25. for /f "tokens=1,2 delims=." %%a in ("!B!") do (
  26. set B1=%%a&set B=!B1!%%b
  27. if "%%b"=="" (set PB=0) else (
  28. set B2=%%b
  29. for %%i in (512 256 128 64 32 16 8 4 2 1) do (
  30.     if not "!B2:~%%i!"=="" (
  31. set/a PB+=%%i
  32. set "B2=!B2:~%%i!"
  33. )
  34. )
  35. if "!B2:~1!"=="" (set/a PB+=1)
  36. )
  37. )
  38. set/a PO=PA+PB
  39. REM 位数信息
  40. CALL :CUT !A! A NA
  41. CALL :CUT !B! B NB
  42. set/a N=NA+NB,NA*=3,NB*=3
  43. echo ======================================
  44. echo 被乘数信息:  有效!NA!位,浮点!PA!位  
  45. echo   乘数信息:  有效!NB!位,浮点!PB!位
  46. echo ======================================
  47. set t1=!time:~-5!
  48. REM 核心乘法
  49. for /l %%i in (1 1 !N!) do (
  50. for /l %%j in (1 1 %%i) do (
  51. set/a j=%%i-%%j+1
  52. if defined A[%%j] (
  53. if defined B[!j!] (
  54. set/a sum=A[%%j]*B[!j!]+sum
  55. )
  56. )
  57. )
  58. set/a s=sum+1000
  59. set sum=!sum:~0,-3!
  60. set pul=!s:~-3!!pul!
  61. )
  62. :DIS 显示结果
  63. if !PO! equ 0 (
  64. for /l %%i in (1 1 5) do (
  65. if "!pul:~0,1!"=="0" (
  66. set pul=!pul:~1!
  67. )
  68. )
  69. echo =!pul!
  70. ) else (
  71. set pre=!pul:~0,-%PO%!
  72. for /l %%i in (1 1 5) do (
  73. if "!pre:~0,1!"=="0" (
  74. set pre=!pre:~1!
  75. )
  76. )
  77. if not defined pre (set pre=0)
  78. echo =!pre!.!pul:~-%PO%!
  79. )
  80. REM 毫秒计时器
  81. set "t2=!time:~-5!" &set/a "t=1!t2:.=!-1!t1:.=!" &if !t! lss 0 (set/a t+=6000)
  82. set/p=耗时!t:~0,-2!秒!t:~-2!0毫秒
  83. endlocal&goto MAIN
  84. :CUT 分割数组
  85. set num=%1
  86. if "!num:~-3!"=="!num:~-4!" (
  87. set %2[1]=!num!
  88. set %3=1
  89. goto :eof
  90. )
  91. for /l %%i in (1 1 365) do (
  92. if "!num:~0,-3!"=="" (
  93. set/a %2[%%i]=!num!
  94. set %3=%%i
  95. goto :eof
  96. )
  97. set/a %2[%%i]=1!num:~-3!-1000
  98. set num=!num:~0,-3%!
  99. )
复制代码
测试 615位大数   35486456354... 乘以 312位大数   35867...用时9秒。for循环的效率以及批处理脆弱的计算能力,导致它远远不及C语言(需要0.3秒).
----------------------------------------------------------------------------------------------------------------------------------------------------------------
下面是大整数加法,1000位加1000位范围内,再多,cmd窗口输不进去。效率基本0.0几秒吧。
  1. @echo off&setlocal enabledelayedexpansion
  2. title By Happy
  3. mode con cols=65 lines=35
  4. REM 大数长度
  5. set "MAX=1000" ^位
  6. REM 分割大小
  7. set "K=8"      ^位
  8. set /a CYC=MAX/K
  9. :MAIN
  10. cls
  11. echo 请输入^(被加数^)
  12. set /p A=-^>:
  13. echo 请输入^(加数^)
  14. set /p B=-^>:
  15. REM 优化字符
  16. setlocal
  17. CALL :POINT !A! A N1
  18. CALL :POINT !B! B N2
  19. set /a B1=N1*K
  20. set /a B2=N2*K
  21. echo ======================================
  22. echo 被加数信息:  预估!B1!位
  23. echo   加数信息:  预估!B2!位
  24. echo ======================================
  25. echo 计算结果
  26. REM 加法核心
  27. if !N1! gtr !N2! (set RM=!N1! &set dx=B) else (set RM=!N2! &set dx=A)
  28. for /l %%i in (1 1 !RM!) do (
  29. if not defined !dx![%%i] (set "!dx![%%i]=00000000")
  30. set /a sum=1!A[%%i]!+1!B[%%i]!+sum
  31. set S=!sum:~-%K%!!S!
  32. set /a sum=!sum:~0,1!-2
  33. )
  34. REM 显示
  35. :DISP
  36. for /l %%i in (1 1 8) do (if "!S:~0,1!"=="0" (set S=!S:~1!))
  37. if "!S!"=="" (set S=0)
  38. echo,!S!
  39. pause>nul
  40. endlocal
  41. goto MAIN
  42. REM 分割数位
  43. :POINT
  44. set num=%1
  45. for /l %%i in (1 1 !CYC!) do (
  46. set %2[%%i]=!num:~-%K%!
  47. set num=!num:~0,-%K%!
  48. if "!num!"=="" (
  49. set /a CU=!%2[%%i]!+100000000
  50. set %2[%%i]=!CU:~-%K%!
  51. set /a %3=%%i
  52. goto :eof
  53. )
  54. )
复制代码
1

评分人数

TOP

本帖最后由 happy886rr 于 2017-1-23 23:02 编辑

回复 15# pcl_test
相当严谨,颇具正则之风。仿佛在读一篇精美的散文。
1

评分人数

TOP

返回列表