通常,我们都知道在保留小数位的时候,常常会用到四舍五入。但是在一些更加专业的场景中,四舍五入往往不够精确。因此,有了“四舍六入五成双”这样一种规则。四舍六入五成双是一种比较精确比较科学的计数保留法,是一种数字修约规则。下图是来自百度百科的解释,感兴趣或者还不太熟悉的朋友可以先搜索看一下。
那有了这样一个背景之后呢,我们想要实现这样一个规则,在excel中需要通过一系列的内置公式进行复合。对于普通用户来说无论是理解还是使用上,都比较繁琐且复杂。那么我们就可以通过自定义函数来完成这样一个需求,这样用户只需要记住或者使用我们自定义的函数名既可使用具有这样一个规则的函数。
关于如何实现自定义函数可以看一下学习指南
https://demo.grapecity.com.cn/sp ... om-functions/purejs
我们首先需要定义函数的名称,以及里面的参数数目。因为我们想要实现的是,传两参数,1是需要被约修的数值,2是保留小数点后面的位数,根据值和位数进行约修。
- var FdaFunction = function() {
- this.name = "FDA";
- this.minArgs = 1;
- this.maxArgs = 2;
- };
复制代码
接下来就是为了方便用户理解和使用,我们需要对这个自定义函数添加一些描述
- FdaFunction.prototype.description = function() {
- return {
- description: "对value进行四舍六入五留双修约,保留小数点后指定位数",
- parameters: [{
- name: "value",
- repeatable: false,
- optional: false
- }, {
- name: "places",
- repeatable: false,
- optional: false
- }]
- }
- }
复制代码 最后关键步骤,也就是函数的逻辑运行都放在evaluate中,在里面,我们会对传入的值做一些判断,并且会利用正则表达式做一些匹配。要实现“五成双”,那么我们还要对需要约修的最后一个位值做判断,来决定是否进位。具体可以参考附件完整的demo。
- FdaFunction.prototype.evaluate = function(context, num, places) {
- if (!isNaN(parseInt(num)) && !isNaN(parseInt(places))) {
- console.log("evaluate")
- num = numGeneral(num);
- if (!isNumber(num)) {
- return num;
- }
- var d = places || 0;
- var m = Math.pow(10, d);
- var n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
- var i = Math.floor(n),
- f = n - i;
- var e = 1e-8; // Allow for rounding errors in f
- var r = f > 0.5 - e && f < 0.5 + e ? (i % 2 == 0 ? i : i + 1) : Math.round(n);
- var result = d ? r / m : r;
- if (places > 0) {
- var s_x = result.toString();
- var pos_decimal = s_x.indexOf(".");
- if (pos_decimal < 0) {
- pos_decimal = s_x.length;
- s_x += ".";
- }
- while (s_x.length <= pos_decimal + places) {
- s_x += "0";
- }
- return s_x;
- } else {
- return result;
- }
- }else{
- return "#VALUE!";
- }
-
- }
复制代码
下载附件即可查看完整demo。
四舍六入v15.html
(10.74 KB, 下载次数: 700)
|
|