Board logo

标题: [数值计算] 批处理怎样实现计算超大数、浮点数? [打印本页]

作者: garyng    时间: 2011-8-30 14:12     标题: 批处理怎样实现计算超大数、浮点数?

大家都知道批处理能处理的数最大是2^31-1(2 147 483 647)到-2^31(-2 147 483 648)对吧~
还有就是批处理不能进行小数点运算对吧?
然后我有个疑问:
批处理怎样实现大数/有小数点的数的加、减、乘、除啊?
翻了论坛的帖子,看到很多是把数分为几个数个一组,过后才合并回去
可是,
看不懂各位高手的代码~
请问这怎样实现啊?
能否给出代码
以及清楚、不太深奥的解释?
满意的——加分!

作者: raymai97    时间: 2011-8-30 14:21

2^31-1(2 147 483 647)?位运算?
这个文章:bbs.bathome.net/thread-1844-1-1.html
我看来看去还是看不明白~
楼主可不可以给个例子啊~
作者: garyng    时间: 2011-8-30 14:32

回复 2# raymai97


    不是位运算啦~况且我连位运算都不知是什么东西呢!例子啊:
如过输入过大/过小的数,
CMD就会翻脸
跳出这个东西:Invalid number.  Numbers are limited to 32-bits of precision.
我的意思是能不能突破这个限制?

能。当然能。
但我求个清楚的解释,和代码~
作者: CrLf    时间: 2011-8-30 16:46

要想突破限制,总要付出代价
作者: CUer    时间: 2011-8-30 17:08

看到很多是把数分为几个数个一组,过后才合并回去

你这不是已经懂了吗?还有啥问题?哪个代码不懂的话,给个链接出来啊
作者: garyng    时间: 2011-8-30 19:35

本帖最后由 pcl_test 于 2017-4-12 21:31 编辑

回复 5# CUer

比如这个http://www.bathome.net/viewthread.php?tid=3372
作者: abcdshenji    时间: 2011-8-30 20:31

本帖最后由 abcdshenji 于 2011-8-30 20:58 编辑

发一段自己写的。。没什么效率可言。。主要是体现个人思路。。
  1. @echo off
  2. call :Add 314649645665.32188 694784.876998798
  3. pause&exit/b
  4. :Add number1 number2 ||@by zj
  5. ::不支持负数
  6. Setlocal EnableDelayedExpansion
  7. set "bjs=%~1"&set "js=%~2"
  8. set "bjs=%bjs:-=%"&set "js=%js:-=%"
  9. for %%i in (bjs js) do (
  10. ((echo !%%i!)|findstr /ic:"."||set "%%i=!%%i!.0")>nul
  11. for /f "tokens=1,2 delims=." %%j in ("!%%i!") do set "z_%%i=%%j"&set "x_%%i=%%k"
  12. )
  13. ::::设定两数的整数和小数部分,整数的给z_XXX,小数的给x_XXX
  14. call :lp z_bjs z_js z_max
  15. for /l %%i in (1 1 %lg_z_max%) do set "z_bjs=0!z_bjs!"&set "z_js=0!z_js!"
  16. call :sub !z_bjs:~-%lg_z_max%!%x_bjs% !z_js:~-%lg_z_max%!%x_js%
  17. ::调用sub求出两数各位数的和,大于10的进1,截取倒数第一位
  18. goto :EOF
  19. :sub num1 num2 ||小数部分(左补零对齐)
  20. Setlocal
  21. set ".bjs=%~1"&set ".js=%~2"
  22. call :lp .bjs .js .max
  23. set/a lg_.max-=1
  24. for /l %%i in (%lg_.max% -1 0) do (
  25. set "x=!.bjs:~%%i,1!"&set "y=!.js:~%%i,1!"
  26. for %%j in (x y p) do (if not defined %%j set "%%j=0")
  27. set/a bit_sum=!x!+!y!+!p:~,1!
  28. set "bit_sum=0!bit_sum!"&set "p=!bit_sum:~-2,1!"
  29. set "sum=!bit_sum:~-1!!sum!"
  30. )
  31. call :lp x_bjs x_js x_max
  32. set "sum=!sum:~,-%lg_x_max%!.!sum:~-%lg_x_max%!"
  33. if "%sum:~-2,2%" equ ".0" (echo %sum:~,-2%) else echo %sum%
  34. Endlocal&goto :EOF
  35. ::最左位则全部截取,这里的sub函数是关键
  36. :LgStr
  37. set "n=0"
  38. :_LgStr
  39. set "str=%~1"&set/a n+=1
  40. if not "!str:~%n%!"=="" goto :_LgStr
  41. goto :EOF
  42. :lp
  43. for %%i in (%~1 %~2) do (call :lgstr !%%i!&set "lg_%%i=!n!")
  44. if !lg_%~1! geq !lg_%~2! (set "lg_%~3=!lg_%~1!") else set "lg_%~3=!lg_%~2!"
  45. goto :EOF
复制代码
我的思路是模拟笔算,跟分组计算其实也差不多。。把两数的计算全部当成小数部分,前面补零,最后用截取来确定所得数的小数点位置。。大概就这样吧。。纯主观,仅参考。。讲的有点乱不知道楼主有没有明白。。个人觉得大量使用CALL是个遗憾。。但只求完成任务。。

说实在的我我不太会表达,可能注释了还是没清楚,将就的看吧,或者不看也罢
作者: garyng    时间: 2011-8-30 20:39

回复 7# abcdshenji


   大大能否在代码内加入注释?我这小菜鸟看不懂~




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