中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [讨论]脚本+算法=四舍五入,精确除法运算(申精)
« [1] [2] [3] »
作者:
标题: [讨论]脚本+算法=四舍五入,精确除法运算(申精) 上一主题 | 下一主题
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 16 楼』:  

稍微简化了下代码

  Quote:

  1. @echo off &SetLocal EnableDelayedExpansion
  2. set /p x=请输入被除数:
  3. set /p y=请输入除数:
  4. set /p n=请输入欲保留的小数的位数:
  5. set /a count=0
  6. set /a bjsh=10
  7. :loop
  8. if %count% geq %n% goto start
  9. set /a bjsh*=10
  10. set /a count+=1
  11. goto loop
  12. :start
  13. set /a rest=%x%*%bjsh%/%y%-%x%*%bjsh%/10/%y%*10
  14. if "%n%"=="0" (set /a last=%x%/%y%) else (
  15. set /a last=%x%*%bjsh%/10/%y%-%x%*%bjsh%/100/%y%*10
  16. )
  17. if %rest% geq 5 set /a last+=1
  18. if "%n%"=="0" echo 结果为:%last% & pause & goto exit
  19. if "%n%"=="1" set /a t=%x%/%y% && echo 结果为:!t!.%last% & pause & goto exit
  20. set /a result=%x%*%bjsh%/100/%y%
  21. set /a end=%n%-1
  22. call echo 结果为:%%result:~0,-%end%%%.%%result:~-%end%%%%%last%% && pause
  23. :exit
         BJSH发表于:  2007-04-01  14:43

flyinspace兄的话我得好好想想

[ Last edited by bjsh on 2007-4-1 at 02:53 PM ]

2007-4-2 03:35
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
flyinspace
银牌会员





积分 1206
发帖 517
注册 2007-3-25
状态 离线
『第 17 楼』:  

我们换个算法。。

1,获取 被除数 / 除数 的结果。
2,获取 被除数 / 除数 的余数。
3,被除数 减去 余数 则为实际整除数。
3,若余数为0,则该数被整除。提示整除,后面输出几个0
4,若不为0,则 实际整除数 / 除数为 实际整数位的值(该值一定准确)
5,获取除数的位数。假设为2位。输出的小数点为7位。(两个值不能大于10)
6,使用循环 余数 * 10(10的9次方)
7,6的结果 / 除数 (然后利用4舍5入的算法)(给出提示)输出小数位
8,输出结果 : %整数位%.%小数位%

如此。精度也满足了。你的要求也达到了。

bjsh 觉得如何?

   此帖被 +2 点积分    点击查看详情   
评分人:【 bjsh 分数: +2  时间:2007-4-2 05:47




知,不觉多。不知,乃求知
2007-4-2 03:49
查看资料  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 18 楼』:  

flyinspace兄确实给了我提醒;

系统只能精确算出第九位;

也就是说最大精确值是八位;

所以我之前的算法在精确上对于数字较小的绝对没有问题;

比如18/7

但是在大数字上比如100000/7 精度要比前者小;也是和系统最大只能算到第九位有关;

所以在这方面采用flyinspace兄的建议;

先求出余数;把大数字化成小数字;在利用余数去继续除

2007-4-2 04:06
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
flyinspace
银牌会员





积分 1206
发帖 517
注册 2007-3-25
状态 离线
『第 19 楼』:  

呵呵,觉得好的话给我加分吧:)

我是不是好赖皮



知,不觉多。不知,乃求知
2007-4-2 04:10
查看资料  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 20 楼』:  

我要修正我前面的话
系统
数字精确度限为 32 位

所以第九位也不是确保算出来的;

例如 set /a p=4000000000/7
C:\>set /a p=4000000000/7
-42138185


所以第八为才是精确算出来的;

所以最后的精确度应为7位

2007-4-2 04:38
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
flyinspace
银牌会员





积分 1206
发帖 517
注册 2007-3-25
状态 离线
『第 21 楼』:  

不过是一个long int的问题。。
精度就在这里啊。

set /a p=400000000 % 7
set /a a=400000000 - % p%
set /a 整数部分=(400000000 - %a%) / 7
上面是一定整除的了。
怎么会9位不精确呢。。。。



知,不觉多。不知,乃求知
2007-4-2 04:49
查看资料  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 22 楼』:  

新的代码 精度为7

  Quote:

  1. @echo off &SetLocal EnableDelayedExpansion
  2. set /p x=请输入被除数:
  3. set /p y=请输入除数:
  4. :n
  5. set /p n=请输入欲保留的小数的位数:
  6. if %n% gtr 7 echo 最大精确度为7位请重新输入 && goto n
  7. set /a count=0
  8. set /a bjsh=10
  9. set /a system_result=%x%/%y%
  10. set /a system_rest=%x%%%%y%
  11. set x=%system_rest%
  12. :loop
  13. if %count% geq %n% goto start
  14. set /a bjsh*=10
  15. set /a count+=1
  16. goto loop
  17. :start
  18. set /a rest=%x%*%bjsh%/%y%-%x%*%bjsh%/10/%y%*10
  19. if "%n%"=="0" (set /a last=%rest%) else (
  20. set /a last=%x%*%bjsh%/10/%y%-%x%*%bjsh%/100/%y%*10
  21. )
  22. if "%n%"=="0" if %rest% geq 5 set /a last=%system_result%+1 && echo 结果为:!last! & pause & goto exit
  23. if %rest% geq 5 set /a last+=1
  24. if "%n%"=="1" echo 结果为:%system_result%.%last% & pause & goto exit
  25. set /a result=%x%*%bjsh%/100/%y%
  26. set /a end=%n%-1
  27. call echo 结果为:%%system_result%%.%%result:~-%end%%%%%last%% && pause
  28. :exit
         BJSH发表于:  2007-04-01  15:44



   此帖被 +2 点积分      点击查看详情   
评分人:【 flyinspace 分数: +2  时间:2007-4-2 04:55


2007-4-2 04:53
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 23 楼』:  

flyinspace兄
说的有理啊

通过循环取余;

有可能任意精度啊

2007-4-2 04:55
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 24 楼』:  

最终代码了;
精确到任何一位

  Quote:

  1. @echo off
  2. set /p x=请输入被除数:
  3. set /p y=请输入除数:
  4. set /p n=请输入欲保留的小数的位数:
  5. set /a end=%n%-1
  6. set /a count=0
  7. set /a system_result=%x%/%y%
  8. set /a rest=%x%%%%y%
  9. set result=%system_result%.
  10. :loop
  11. set /a rest*=10
  12. set /a last=%rest%/%y%
  13. set /a count+=1
  14. if %count% geq %n% set /a rest=%rest%%%%y%*10/%y% && goto jump_loop
  15. set result=%result%%last%
  16. set /a rest=%rest%%%%y%
  17. goto loop
  18. :jump_loop
  19. if %n%==0 if %last% geq 5 set /a result+=1 && echo 结果为:!result!&& goto exit
  20. if %rest% geq 5 set /a last+=1
  21. echo %result%%last% & pause
         BJSH发表于:  2007-04-01  18:28

[ Last edited by bjsh on 2007-4-1 at 06:40 PM ]

2007-4-2 05:46
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 25 楼』:  

这个代码的思想要归功于flyinspace
本想给他加十分;可惜论坛限制只能加两分..

愿看过的各位 替我实现愿望

2007-4-2 05:49
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 26 楼』:  

以前的那些突破了下限;
无法计算高于10^9次的下面这个经过修改后;突破了上下限;
可以计算任意位数字;并且可以精确到任意位数;(似乎太大比如1百万位会提示输出行太长)

  Quote:

  1. @echo off & setlocal enabledelayedexpansion
  2. set /p x=请输入被除数:
  3. set /p y=请输入除数:
  4. if %y% gtr 2000000000 echo 除数太大 && goto exit
  5. set /p n=请输入欲保留的小数的位数:
  6. if %x% gtr 2000000000 goto big
  7. :start
  8. set /a count=0
  9. set /a system_result=%x%/%y%
  10. set /a rest=%x%%%%y%
  11. set result=%system_result%.
  12. :loop
  13. set /a rest*=10
  14. set /a last=%rest%/%y%
  15. set /a count+=1
  16. if %count% geq %n% set /a rest=%rest%%%%y%*10/%y% && goto jump_loop
  17. set result=%result%%last%
  18. set /a rest=%rest%%%%y%
  19. goto loop
  20. :jump_loop
  21. if %n%==0 if %last% geq 5 set /a result+=1 && echo 结果为:!result!&& goto exit
  22. if %rest% geq 5 set /a last+=1
  23. echo 结果为:%result%%last% && goto exit
  24. :big
  25. set /a l=0
  26. set result=
  27. :big_loop
  28. set p=%x:~0,1%
  29. set /a m=%l%*10+%p%
  30. set /a s=%m%/%y%
  31. set result=%result%%s%
  32. if "%result%"=="0" set result=
  33. set /a l=%m%%%%y%
  34. set x=%x:~1%
  35. if not defined x goto big_end
  36. goto big_loop
  37. :big_end
  38. set result=%result%.
  39. set /a count=0
  40. set rest=%l%
  41. goto loop
  42. :exit
  43. pause
         BJSH发表于:  2007-04-01  18:56

[ Last edited by bjsh on 2007-11-22 at 10:30 PM ]

   此帖被 +2 点积分    点击查看详情   
评分人:【 nanhui112 分数: +2  时间:2008-1-28 16:45


2007-4-2 07:45
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 27 楼』:  

无法解决除数大于10^9的问题

[ Last edited by bjsh on 2007-4-1 at 08:53 PM ]

2007-4-2 08:01
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
flyinspace
银牌会员





积分 1206
发帖 517
注册 2007-3-25
状态 离线
『第 28 楼』:  



  Quote:
Originally posted by bjsh at 2007-4-1 07:01 PM:
无法解决被除数大于10^9的问题

被除数 / 除数 = 结果中。

被除数是可以大于10的9次方的。。
但除数不可以。。

set 被除数=9999999999999999999999999999999
假设这个9有20位。。当然长度可以任意。。

使用 set new=%被除数:~0,9%取9位数出来。。

当然在应用级别的时候。。我们会用for循环解决连续值的问题。。

这里只说明一种情况。。其他的情况你自己搞定啊:)

首先判断 new 是否大于 除数
是--》大于则开始做取余运算。。。

假设除数是111111110。

然后按照上面的方法获得精确的值后。。

获取余数的位数。。

此例子为一位。。。值为9。。

然后在后面利用 set 补上8位。。

如此,循环。。。

把20位的数字全部取完。。
则整数部分的代码搞定了。。
小数部分你自己也会搞啦。。



知,不觉多。不知,乃求知
2007-4-2 09:26
查看资料  发短消息 网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 29 楼』:  

我上面写错了;

是没法解决 除数大于 10^9 的问题;

至于被除数我最后一个代码用的思想和 flyinspace是一样的;

那段代码 对于被除数任意位都可以的

[ Last edited by bjsh on 2007-4-1 at 08:51 PM ]

2007-4-2 09:49
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
nanhui112
初级用户





积分 127
发帖 59
注册 2007-11-13
状态 离线
『第 30 楼』:  

;)特大数 我采取循环截取取数   但还是有问题  如123456789123456
先取前九位计算 后面再补0 把结果相加计算 有涉及到特大数相加的问题
并且结果也不是很正确 涉及到小数问题 一放大 就有很大数字差距了
看来  cmd  不适合计算  只能做到这个份拉~~~
----前面的都是高手 学习拉 加倍努力拉:)

[ Last edited by nanhui112 on 2008-1-28 at 04:43 PM ]

2008-1-28 16:28
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] [3] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: