需求背景:“”四舍六入五成双“”这种修约方式被称为“银行家舍入法”(Banker's Rounding),因为它倾向于产生更少的舍入偏差,并且在中国国家标准《GB/T 8170-2008数值修约规则与极限数值的表示和判定》中有明确规定。这种方法可以应用于各种需要数值修约的场合,如金融计算、统计分析等,以尽量减少由于舍入引起的系统性误差。四舍六入五成双在线下Excel中,部分用户可能会考虑用自定义函数来实现。业务迁移到线上Excel时,由于浏览器无法识别宏语言,因此需要使用浏览器可以识别的js语言来实现这些函数需求。
本文结合spreadjs自定义函数,在全局注册了名为FDA的函数,来完成SpreadJS上的四舍六入。实现之前,我们先来了解一下算法原理。
舍:如果要舍弃的数字小于5(即0、1、2、3或4),则直接舍去这些数字,保留的数字不变。
六入:如果要舍弃的数字大于5(即6、7、8或9),则进位,即将前一位数字加1。
五成双:如果要舍弃的数字是5,则根据具体情况决定是否进位;
如果5后面的数字不全是0,则无论5前面的数字是奇数还是偶数,都进位。
如果5后面没有数字或者后面的数字全部为0,则看5前面的数字:
如果5前面的数字是偶数,则舍去5,不进位。
如果5前面的数字是奇数,则进位,即将前一位数字加1
实现代码:
- let FdaFunction = function () { };
- FdaFunction.prototype = new GC.Spread.CalcEngine.Functions.Function(
- "FDA", 1, 2, {
- description: "四舍六入五成双", //单元格输入函数时对应的提示信息
- //parameters是对函数每个参数的描述,对应的是一个Object的数组
- parameters: [
- {
- name: 'num', //参数的名字,输入函数中的参数时会显示
- repeatable: false, //参数是否可以重复,一般只有最后一个参数可重复
- optional: false //参数是否可选
- },{
- name: 'decimals', //参数的名字,输入函数中的参数时会显示
- repeatable: false, //参数是否可以重复,一般只有最后一个参数可重复
- optional: false //参数是否可选
- }
- ]
- }
- )
- FdaFunction.prototype.evaluate = function (value, decimalPlaces) {
- if (typeof value !== 'number' || isNaN(value)) {
- throw new Error('The first argument must be a valid number.');
- }
- if (!Number.isInteger(decimalPlaces) || decimalPlaces < 0) {
- decimalPlaces = 2
- }
-
- // 计算修约所需的乘数因子
- const factor = Math.pow(10, decimalPlaces);
-
- // 将数值放大指定倍数并提取整数部分和小数部分
- const scaledValue = value * factor;
- const integerPart = Math.floor(scaledValue);
- const fractionalPart = scaledValue - integerPart;
-
- let roundedValue;
-
- if (fractionalPart < 0.5) {
- // 四舍
- roundedValue = integerPart;
- } else if (fractionalPart > 0.5) {
- // 六入
- roundedValue = integerPart + 1;
- } else {
- // 五成双
- if (integerPart % 2 === 0) {
- // 偶数时舍去
- roundedValue = integerPart;
- } else {
- // 奇数时进位
- roundedValue = integerPart + 1;
- }
- }
-
- // 将结果缩小回原比例
- return roundedValue / factor;
- };
- GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("FDA", new FdaFunction());
复制代码 注册完成后,就可以正常使用了:
详细代码参考附件文件。
|
|