|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
本帖最后由 aoe1981 于 2019-12-15 11:22 编辑
写本帖是因为前帖:
请教四舍五入、五舍六入、四舍六入五成双的函数!
http://club.excelhome.net/thread-1089213-1-1.html
(出处: ExcelHome技术论坛)
粗糙且愚蠢。
今日发帖,略微深入,唯愿保证正确。
所谓“统一的求近似数自定义函数:n舍m入”,看名字也很多余,但我做的实际功能比名字上显示的多一些,主要有:
(一)n舍m入,m-n=1
具体有:
不舍0入:即“进一法",实现结果上要与ROUNDUP()完全一致;
0舍1入;
1舍2入;
2舍3入;
3舍4入;
4舍5入;
5舍6入;
6舍7入;
7舍8入;
8舍9入;
9舍不入:即”去尾法",实现结果上要与ROUNDDOWN()完全一致。
如图:
(二)n舍m入n+1或m-1成双,m-n=2
具体有:
8舍9成双;
7舍9入8成双;
6舍8入7成双;
5舍7入6成双;
4舍6入5成双;
3舍5入4成双;
2舍4入3成双;
1舍3入2成双;
0舍2入1成双;
特殊地:“1入0成双”是不行的,因为保留位后的尾数全为0时,首选是等于原数。
如图:
(三)n舍m入余扩展(扩展1位按4舍5入处理),m-n>2
不一而足,如:
3舍7入4、5、6按尾数部分第二位四舍五入扩展保留至尾数部分第一位;
……
如图:
下面说说自定义函数本身:
代码如下:
- Option Explicit
- '成功版:最好用InStr(num & "", ".") = 0判断整数
- '求近似数:n舍m入(精确数,近似位数,n舍,m入)
- Public Function nSmR(num#, Optional ws% = 0, Optional n% = 4, Optional m% = 5)
- Dim fh%, w0%, w1%, w2%
- If n < -1 Or n > 9 Then nSmR = "n错误": Exit Function
- If m < 0 Or m > 10 Then nSmR = "m错误": Exit Function
- If n >= m Then nSmR = "n≥m": Exit Function
- If num >= 0 Then fh = 1 Else fh = -1: num = Abs(num)
- num = num * 10 ^ ws '第一次位移
- w0 = Val(Right(Int(num), 1)) '保留位
- If InStr(num & "", ".") = 0 Then
- nSmR = fh * num * 10 ^ -ws
- Else
- num = num * 10 '第二次位移
- w1 = Val(Right(Int(num), 1)) '尾数部分第一位
- If w1 <= n Then
- nSmR = Val(fh * Int(num / 10) * 10 ^ -ws)
- ElseIf w1 >= m Then
- nSmR = Val(fh * (Int(num / 10) + 1) * 10 ^ -ws)
- Else
- If m - n = 2 Then
- If InStr(num & "", ".") = 0 Then
- If w0 And 1 Then '奇入
- nSmR = Val(fh * (Int(num / 10) + 1) * 10 ^ -ws)
- Else '偶舍
- nSmR = Val(fh * Int(num / 10) * 10 ^ -ws)
- End If
- Else
- nSmR = Val(fh * (Int(num / 10) + 1) * 10 ^ -ws)
- End If
- Else
- num = num * 10 '第三次位移
- w2 = Val(Right(Int(num), 1)) '尾数部分第二位
- If w2 <= 4 Then
- nSmR = Val(fh * Int(num / 10) * 10 ^ -(ws + 1))
- Else
- nSmR = Val(fh * (Int(num / 10) + 1) * 10 ^ -(ws + 1))
- End If
- End If
- End If
- End If
- End Function
复制代码
用法:
求近似数:nSmR(精确数num,近似位数ws,n舍,m入)
其中:
精确数num支持正数、负数;
近似位数ws正数表示小数部分第几位,0表示近似到个位,负数表示整数部分其他位,例如:2表示近似到百分位,0表示近似到个位,-2表示近似到百位;
如图:
n的取值范围为:{-1,0,1,2,3,4,5,6,7,8,9},m的取值范围为:{0,1,2,3,4,5,6,7,8,9,10},且n<m;
n=-1,m=0时,相当于ROUNDUP(),如图(通过随机值连续按F9测试正确):
n=9,m=10时,相当于ROUNDDOWN(),如图(通过随机值连续按F9测试正确):
接下来是附件,包含完整测试过程。
求近似数:n舍m入.zip
(35.66 KB, 下载次数: 16)
(增加了新的“误差测试”,详情见5楼。)
一些编写过程中的奇葩意外下楼再说。
|
评分
-
1
查看全部评分
-
|