楼 主
[讨论]脚本+算法=四舍五入,精确除法运算(申精)
发表于 2007-04-01 23:51 · 中国 广东 广州 联通
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
突然在帖子里看到了一个关于四舍五入的请教问题!
心里还在笑笑,CMD又不支持四舍五入运算。
但就在转过去看其他的帖子的时候,却灵机一动,想出了如下算法。。
现在把自己的算法写在下面。希望和高手们一起进步。
也希望高手们可以精简自己的代码。
——————————————————————————————————
思想:
取 除法的 余数 ,若余数减去 被除数的二分之一能大于 0 就证明这个数为5入运算。否则为4舍运算。
加入了对余数的判断,因为余数只能是2n或 2N+1 .若为2n+1,则该数/2后满足4舍5入的条件。若不是,则继续下面的判断
——————————————————————————————————
@echo off & SetLocal EnableDelayedExpansion
set /a 除数=25
set /a 被除数=10
set /a 余数=%除数% %% %被除数%
set /a 参考值=%被除数%/2
set /a 参考值1=%被除数%-%参考值%*2
set /a 进位=%余数%-(%参考值%+%参考值1%)
echo %参考值%,参考值1,%进位%
if %进位% LSS 0 (
echo %除数% ÷ %被除数% 的结果为 4舍运算!
set /a 结果=%除数%/%被除数%
) else (
echo %除数% ÷ %被除数% 的结果为 5入运算!
set /a 结果=%除数%/%被除数%+1
)
echo 答案为:%结果%
pause
--------------------------------------------------------------------------------------------
在这里我只是抛了一块砖。。却引了一块玉出来。。
大家看看bjsh的代码,一次比一次完善。。
现在基本可以应付任意位数的除法运算,且保证精度了。
大家多给bjsh加分吧:)
[ Last edited by flyinspace on 2007-4-1 at 08:33 PM ]
知,不觉多。不知,乃求知
第 2 楼
发表于 2007-04-02 00:06 · 中国 湖北 武汉 电信
版主
★★★★★
积分 11,386
发帖 4,938
注册 2006-07-23 17:10
UID 59080
状态 离线
思路不错,可惜还是不能突破“批处理不能做四舍五入”这个难关。
用27/5试试。
第 3 楼
发表于 2007-04-02 00:26 · 中国 广东 广州 联通
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
谢谢lxmxn的指出
现在问题已经解决。。
另:拷贝文件时进度条显示进度问题已经解决!
复制文件时,可以看到拷贝的进度了。
只是会产生临时文件。
在硬盘速度过快,拷贝文件过大的情况下有1~3秒的显示差异。
现在考虑修改这个显示问题中。
[ Last edited by flyinspace on 2007-4-1 at 02:04 PM ]
知,不觉多。不知,乃求知
第 4 楼
发表于 2007-04-02 00:49 · 中国 陕西 西安 电信
铂金会员
★★★★
积分 5,212
发帖 2,478
注册 2007-02-08 23:39
UID 79003
性别 男
状态 离线
@echo off & SetLocal EnableDelayedExpansion
set /p 除数=
set /p 被除数=
set /a 余数=%除数% %% %被除数%
set /a 参考值=%被除数%/2
if %余数% LSS %参考值% (
echo %除数% ÷ %被除数% 的结果为 4舍运算!
set /a 结果=%除数%/%被除数%
) else (
echo %除数% ÷ %被除数% 的结果为 5入运算!
set /a 结果=%除数%/%被除数%+1
)
echo 答案为:%结果%
pause
直接判断余数和被除数的1/2不行?为什么要-然后和0比大小?
第 5 楼
发表于 2007-04-02 01:02 · 中国 广东 广州 联通
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
呵呵,当然行啊。。。。。但现在你复制的这个代码会有问题。
在特殊情况下会出现判断错误的情况。。
回4楼。有道理,是我多做了一下判断。。
准备写个批处理和c程序做除数1-100000 被除数 1-100000的测试。
看代码会不会出现误判的情况。。
知,不觉多。不知,乃求知
第 6 楼
发表于 2007-04-02 02:27 · 中国 浙江 杭州 华数宽带
银牌会员
★★★
积分 2,000
发帖 621
注册 2007-01-01 00:00
UID 75212
性别 男
状态 离线
这是我写的;
精确到你指定的小数点位;四舍五入的;大家帮忙测试下
代码可以再精简的;有时间的话把精简后的发上来;
大家也可以帮忙精简下代码
- @echo off &SetLocal EnableDelayedExpansion
- set /p x=请输入被除数:
- set /p y=请输入除数:
- set /p n=请输入欲保留的小数的位数:
- set /a count=0
- set /a bjsh=10
- :loop
- if %count% geq %n% goto start
- set /a bjsh*=10
- set /a count+=1
- goto loop
- :start
- set /a rest=%x%*%bjsh%/%y%-%x%*%bjsh%/10/%y%*10
- if "%n%"=="0" (set /a last=%x%/%y%) else (
- set /a last=%x%*%bjsh%/10/%y%-%x%*%bjsh%/100/%y%*10
- )
- if %rest% geq 5 set /a last+=1
- if "%n%"=="0" echo 结果为%last% & pause & goto exit
- set /a result=%x%/%y%
- set result=%result%.
- set /a end=%n%-1
- set /a bjsh=10
- for /l %%i in (1,1,%end%) do (
- set /a add=%x%*!bjsh!/%y%-%x%*!bjsh!/10/%y%*10
- set result=!result!!add!
- set /a bjsh*=10
- )
- set result=%result%%last%
- echo 结果为%result% & pause
- :exit
BJSH发表于: 2007-04-01 13:22
[
Last edited by bjsh on 2007-4-1 at 01:32 PM ]
第 7 楼
发表于 2007-04-02 02:44 · 中国 广东 广州 海珠区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
呵,算法只是提供一种思路而已。。
。不过bjsh真的把这个发挥得不错:)
至于测试嘛。。我想就算了:)
精度不高。不如不测试。
而且既然已经准备写到实用的级别。。
就应该对错误进行判断了。
要不然,这个就没有意义。
知,不觉多。不知,乃求知
第 8 楼
发表于 2007-04-02 02:48 · 中国 浙江 杭州 华数宽带
银牌会员
★★★
积分 2,000
发帖 621
注册 2007-01-01 00:00
UID 75212
性别 男
状态 离线
是的
只能精确到小数点后八位;
再高就会出现随机数字了;
搞到百位以上就会出现莫名其妙的-和数字的组合了;
到这里应该是和系统有关了
第 9 楼
发表于 2007-04-02 02:52 · 中国 浙江 杭州 华数宽带
银牌会员
★★★
积分 2,000
发帖 621
注册 2007-01-01 00:00
UID 75212
性别 男
状态 离线
我写的代码的算法倒是和flyinspace的不同
flyinspace兄的算法是
取 除法的 余数 ,若余数减去 被除数的二分之一能大于 0 就证明这个数为5入运算
我的是:利用把实际结果10^n放大取到欲精确的位的后一位;然后进行判断
{/color]
第 10 楼
发表于 2007-04-02 02:53 · 中国 广东 广州 海珠区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
嗯。那么第一点。需要对输入的位数进行判断!尽量不出现随机数字。。
第二,屏蔽到后面的随机数字。。
第三,出错处理机制。
我想这一点应该不难吧。
知,不觉多。不知,乃求知
第 11 楼
发表于 2007-04-02 02:57 · 中国 浙江 杭州 华数宽带
银牌会员
★★★
积分 2,000
发帖 621
注册 2007-01-01 00:00
UID 75212
性别 男
状态 离线
嗯;
那倒是挺简单的
判断%n% geq 8 提示 精确度不能高于8位; 后面也用不到屏蔽了
至于出错机制;
也只有在前面判断
x y n 是否为数字就可以了;
这个东西我就不加进去了;留给想用的人加吧;反正也就几行代码的问题
第 12 楼
发表于 2007-04-02 03:01 · 中国 广东 广州 海珠区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
呵呵,试一下
100000 / 7
嗯。。你也考虑一下dos进度条实用性的问题吧。。
[ Last edited by flyinspace on 2007-4-1 at 02:05 PM ]
知,不觉多。不知,乃求知
第 13 楼
发表于 2007-04-02 03:09 · 中国 浙江 杭州 华数宽带
银牌会员
★★★
积分 2,000
发帖 621
注册 2007-01-01 00:00
UID 75212
性别 男
状态 离线
用100000/7
只能精确到5位;而且因为第6位不准所以第五位也是不准的;
是不是可以想出一种办法可以是精确度再提高啊
第 14 楼
发表于 2007-04-02 03:14 · 中国 浙江 杭州 华数宽带
银牌会员
★★★
积分 2,000
发帖 621
注册 2007-01-01 00:00
UID 75212
性别 男
状态 离线
用 18/7算了一下;
可以精确到第8位但是第八位也是不准的;
精确到7位是准的;
100000/7 和 18/7 的区别在于位数;
所以10^n放大确实会影响精确度的;
隐约感觉 改进算法会提高精确度;虽然系统本身就存在精确度限制;
但是应该可以发挥到极致
第 15 楼
发表于 2007-04-02 03:28 · 中国 广东 广州 海珠区 电信
银牌会员
★★★
积分 1,206
发帖 517
注册 2007-03-25 01:18
UID 82819
性别 男
状态 离线
嗯。。看一下你自己的算法。你就明白啦:)
把结果只截取你自己估算的精度出来。
而不只是对输入进行判断。输入只是为了在一定程度上帮助用户不走弯路而已。
核心的还是你自己的脚本代码问题。
你觉得呢??bjsh 兄。
知,不觉多。不知,乃求知
论坛跳转: