jquery中 toFixed()的坑

本文深入探讨了toFixed()方法中独特的四舍六入五取偶规则,这是一种不同于传统四舍五入的数值处理方式,特别关注于小数点后五的处理逻辑,即在遇到五时依据前一位的奇偶性决定进位与否。

 

与平常的四舍五入的方式不同,toFixed()方法,采用四舍六入五取偶的方式

四舍六入五取偶:特殊情况下简单来说就是,所要保留的小数位,当遇到五的时候,根据五前面一位是否为偶数进行判断,是偶数,进一位;否则,就舍去 

这是我们公司的流程js,帮我分析下结构,开发步骤,我是0基础 //采购需求申请表 //convertFieldNameToId函数:将字段名称转换成字段id var szgs_fid = WfForm.convertFieldNameToId("szgs"); //所属公司 var department_fid = WfForm.convertFieldNameToId("department"); //申请部门 var username_fid = WfForm.convertFieldNameToId("username"); //申请人 var cdate_fid = WfForm.convertFieldNameToId("cdate"); //申请日期 var sqdl_fid = WfForm.convertFieldNameToId("sqdl"); //申请大类 var oabh_fid = WfForm.convertFieldNameToId("oabh"); //OA编号 var dqjdmc_fid = WfForm.convertFieldNameToId("dqjdmc"); //当前节点名称 var lcbt_fid = WfForm.convertFieldNameToId("lcbt"); //流程标题 var tsy_fid = WfForm.convertFieldNameToId("tsy"); //提示语 var bmzx_fid = WfForm.convertFieldNameToId("bmzx"); //提示语 var sqlb_fid_dt1 = WfForm.convertFieldNameToId("sqlb","detail_1");//申请类别 var xmmc_fid_dt1 = WfForm.convertFieldNameToId("xmmc","detail_1");//项目名称 var ggxh_fid_dt1 = WfForm.convertFieldNameToId("ggxh","detail_1");//规格型号 var npjyl_fid_dt1 = WfForm.convertFieldNameToId("npjyl","detail_1");//年平均用量 var zqyl_fid_dt1 = WfForm.convertFieldNameToId("zqyl","detail_1");//周期用量 var scjysj_fid_dt1 = WfForm.convertFieldNameToId("scjysj","detail_1");//首次交样时间 var scjysl_fid_dt1 = WfForm.convertFieldNameToId("scjysl","detail_1");//首次交样数量 var sjfj_fid_dt1 = WfForm.convertFieldNameToId("sjfj","detail_1");//数据附件 var cgqrgyslb_fid_dt1 = WfForm.convertFieldNameToId("cgqrgyslb","detail_1");//采购确认供应商类别 var sqlb_fid_dt2 = WfForm.convertFieldNameToId("sqlb","detail_2");//申请类别 var pp_fid_dt2 = WfForm.convertFieldNameToId("pp","detail_2");//品牌 var ggxh_fid_dt2 = WfForm.convertFieldNameToId("ggxh","detail_2");//规格型号 var xqms_fid_dt2 = WfForm.convertFieldNameToId("xqms","detail_2");//需求描述 var sl_fid_dt2 = WfForm.convertFieldNameToId("sl","detail_2");//数量 var xqdwsj_fid_dt2 = WfForm.convertFieldNameToId("xqdwsj","detail_2");//需求到位时间 var cgqrgyslb_fid_dt2 = WfForm.convertFieldNameToId("cgqrgyslb","detail_2");//采购确认供应商类别 WfForm.changeFieldAttr(tsy_fid, 1);//提示语设置为只读 /* WfForm.changeFieldAttr(szgs_fid,2);//所属公司 WfForm.changeFieldAttr(department_fid,2);//申请部门 WfForm.changeFieldAttr(username_fid,2);//申请人 WfForm.changeFieldAttr(cdate_fid,2);//申请日期 WfForm.changeFieldAttr(sqdl_fid,2);//申请大类 WfForm.changeFieldAttr(oabh_fid,2);//OA编号 WfForm.changeFieldAttr(dqjdmc_fid,2);//当前节点名称 WfForm.changeFieldAttr(lcbt_fid,2);//流程标题 WfForm.changeFieldAttr(sqlb_fid_dt1+"_"+rowIndex,3);//申请类别 WfForm.changeFieldAttr(xmmc_fid_dt1+"_"+rowIndex,3);//项目名称 WfForm.changeFieldAttr(ggxh_fid_dt1+"_"+rowIndex,3);//规格型号 WfForm.changeFieldAttr(npjyl_fid_dt1+"_"+rowIndex,3);//年平均用量 WfForm.changeFieldAttr(zqyl_fid_dt1+"_"+rowIndex,3);//周期用量 WfForm.changeFieldAttr(scjysj_fid_dt1+"_"+rowIndex,3);//首次交样时间 WfForm.changeFieldAttr(scjysl_fid_dt1+"_"+rowIndex,3);//首次交样数量 WfForm.changeFieldAttr(sjfj_fid_dt1+"_"+rowIndex,3);//数据附件 WfForm.changeFieldAttr(sqlb_fid_dt2+"_"+rowIndex,3);//申请类别 WfForm.changeFieldAttr(pp_fid_dt2+"_"+rowIndex,3);//品牌 WfForm.changeFieldAttr(ggxh_fid_dt2+"_"+rowIndex,3);//规格型号 WfForm.changeFieldAttr(xqms_fid_dt2+"_"+rowIndex,3);//需求描述 WfForm.changeFieldAttr(sl_fid_dt2+"_"+rowIndex,3);//数量 WfForm.changeFieldAttr(xqdwsj_fid_dt2+"_"+rowIndex,3);//需求到位时间 */ //明细1 //changeFieldAttr 函数:改变单个字段显示属性(只读/必填等) //条件: // 第一个:字段标示,格式field${字段ID}_${明细行号} // 第二个:改变字段的状态,1:只读,2:可编辑,3:必填,4:隐藏字段标签及内容,5:隐藏字段所在行(行内单元格不要存在行合并) function dt1_edit_ctrl(){ //WfForm.delDetailRow("detail_2", "all"); var rowArr = WfForm.getDetailAllRowIndexStr("detail_1").split(","); // 获取明细表1的所有行标 for (var i = 0; i < rowArr.length; i++) { rowIndex = rowArr[i]; if (rowIndex == "") continue; WfForm.changeFieldAttr(sqlb_fid_dt1 + "_" + rowIndex, 3);//申请类别 WfForm.changeFieldAttr(xmmc_fid_dt1+"_"+rowIndex,3);//项目名称 WfForm.changeFieldAttr(ggxh_fid_dt1+"_"+rowIndex,3);//规格型号 WfForm.changeFieldAttr(npjyl_fid_dt1+"_"+rowIndex,3);//年平均用量 WfForm.changeFieldAttr(zqyl_fid_dt1+"_"+rowIndex,3);//周期用量 WfForm.changeFieldAttr(scjysj_fid_dt1+"_"+rowIndex,3);//首次交样时间 WfForm.changeFieldAttr(scjysl_fid_dt1+"_"+rowIndex,3);//首次交样数量 WfForm.changeFieldAttr(sjfj_fid_dt1+"_"+rowIndex,2);//数据附件 WfForm.changeFieldAttr(cgqrgyslb_fid_dt1+"_"+rowIndex,3);//采购确认供应商类别 } }; //明细2 function dt2_edit_ctrl(){ //WfForm.delDetailRow("detail_1", "all"); var rowArr = WfForm.getDetailAllRowIndexStr("detail_2").split(","); // 获取明细表1的所有行标 for (var i = 0; i < rowArr.length; i++) { rowIndex = rowArr[i]; if (rowIndex == "") continue; WfForm.changeFieldAttr(sqlb_fid_dt2+"_"+rowIndex,3);//申请类别 WfForm.changeFieldAttr(pp_fid_dt2+"_"+rowIndex,3);//品牌 WfForm.changeFieldAttr(ggxh_fid_dt2+"_"+rowIndex,3);//规格型号 WfForm.changeFieldAttr(xqms_fid_dt2+"_"+rowIndex,3);//需求描述 WfForm.changeFieldAttr(sl_fid_dt2+"_"+rowIndex,3);//数量 WfForm.changeFieldAttr(xqdwsj_fid_dt2+"_"+rowIndex,3);//需求到位时间 WfForm.changeFieldAttr(cgqrgyslb_fid_dt2+"_"+rowIndex,3);//采购确认供应商类别 } }; //发起 function node_4476_ctrl(){ WfForm.changeFieldAttr(szgs_fid,3);//所属公司 WfForm.changeFieldAttr(department_fid,3);//申请部门 WfForm.changeFieldAttr(username_fid,3);//申请人 WfForm.changeFieldAttr(cdate_fid,1);//申请日期 WfForm.changeFieldAttr(sqdl_fid,3);//申请大类 WfForm.changeFieldAttr(bmzx_fid,3);//申请大类 dt1_edit_ctrl(); dt2_edit_ctrl(); // 加行控制 WfForm.registerAction(WfForm.ACTION_ADDROW + "1", function (rowindex) { dt1_edit_ctrl(); }); WfForm.registerAction(WfForm.ACTION_ADDROW + "2", function (rowindex) { dt2_edit_ctrl(); }); //RihanUtils.add_detail_Ctrl("1",dt1_edit_ctrl,"add","dt1_addline_butten");//添加明细1 //RihanUtils.add_detail_Ctrl("2",dt2_edit_ctrl,"add","dt2_addline_butten");//添加明细2 }; //部门经理审核 function node_4477_ctrl(){ }; //工厂总经理审批/总部商务副总 function node_4479_ctrl(){ }; //采购部协同 function node_4480_ctrl(){ }; //商务总监 function node_4481_ctrl(){ }; //总部商务副总 function node_4482_ctrl(){ }; //结束 function node_4478_ctrl(){ }; jQuery(document).ready(function() { node_id = WfForm.getBaseInfo().nodeid; wf_id = WfForm.getBaseInfo().workflowid; node_name = wfform.getGlobalStore().commonParam.nodename; var wf_name = wfform.getGlobalStore().commonParam.workflowname; WfForm.changeFieldValue(dqjdmc_fid,{value:node_name}); WfForm.changeFieldValue(lcbt_fid,{value:wf_name}); // 获取申请大类的值 var sqdl_fid_value = WfForm.getFieldValue(sqdl_fid); // 根据申请大类的值显示不同的tab并自动切换到当前tab showAndActivateTab(sqdl_fid_value); WfForm.bindFieldChangeEvent(sqdl_fid, function(obj, id, sqdl_fid_value){ showAndActivateTab(sqdl_fid_value); }); //注册拦截事件,指定动作执行前触发,并可阻断/放行后续操作 // 提交时,根据申请大类判断明细是否有值 WfForm.registerCheckEvent(WfForm.OPER_SUBMIT, function(callback) { // 校验逻辑 var flag = false // 获取申请大类的值 var sqdl_fid_value = WfForm.getFieldValue(sqdl_fid); if (sqdl_fid_value == 0) { //产品类 var rowArr = WfForm.getDetailAllRowIndexStr("detail_1").split(","); // 获取明细表1的所有行标 rowIndex = rowArr[0]; if (rowIndex != "") { flag = true } } else { var rowArr = WfForm.getDetailAllRowIndexStr("detail_2").split(","); // 获取明细表2的所有行标 rowIndex = rowArr[0]; if (rowIndex != "") { flag = true } } if (flag) { callback(); // 继续提交 } else { // 阻止提交并显示错误信息 WfForm.showConfirm("请新增产品类/非产品类明细", function(){}, function(){},{okText:"确认"}); } }); switch (node_id) { case 4476: /*发起*/ node_4476_ctrl(); break; case 4477: /*部门经理审核*/ node_4477_ctrl(); break; case 4479: /*工厂总经理审批*/ node_4479_ctrl(); break; case 4480: /*采购部协同*/ node_4480_ctrl(); break; case 4481: /*商务总监*/ node_4481_ctrl(); break; case 4482: /*总部商务副总*/ node_4482_ctrl(); break; case 4478: /*结束*/ node_4478_ctrl(); break; default: console.warn("未知节点ID:", node_id); break; } }); //是否是用户确认不切换,系统自动将申请大类回退到原来的值 var sqdl_flag = false; //切换申请大类选择值 function showAndActivateTab(sqdl_fid_value) { if (!sqdl_flag) { if (sqdl_fid_value == 0) { //选择产品类时,先去非产品类查看是否已经填写 var rowArr = WfForm.getDetailAllRowIndexStr("detail_2").split(","); // 获取明细表1的所有行标 let rowIndex = rowArr[0]; if (rowIndex != "") { //已经填写,要提示 WfForm.showConfirm("非产品类明细已填写内容,如果切换到产品类明细,非产品类明细将会删除。您确定要切换到产品类?", function(){ //用户确认切换 WfForm.delDetailRow("detail_2", "all"); }, function(){ sqdl_fid_value == 1; WfForm.changeFieldValue(sqdl_fid, {value: 1}); sqdl_flag = true window.setTimeout(function() { sqdl_flag = false }, 500); }, { title:"信息确认", //弹确认框的title,仅PC端有效 okText:"确定", //自定义确认按钮名称 cancelText:"取消" //自定义取消按钮名称 }); } showAndActivateTabAct(sqdl_fid_value); } else { //选择非产品类时,先去产品类查看是否已经填写 var rowArr = WfForm.getDetailAllRowIndexStr("detail_1").split(","); // 获取明细表1的所有行标 let rowIndex = rowArr[0]; if (rowIndex != "") { //已经填写,要提示 WfForm.showConfirm("产品类明细已填写内容,如果切换到非产品类明细,产品类明细将会删除。您确定要切换到非产品类?", function(){ //用户确认切换 WfForm.delDetailRow("detail_1", "all"); }, function(){ sqdl_fid_value == 0; WfForm.changeFieldValue(sqdl_fid, {value: 0}); sqdl_flag = true window.setTimeout(function() { sqdl_flag = false }, 500); }, { title:"信息确认", //弹确认框的title,仅PC端有效 okText:"确定", //自定义确认按钮名称 cancelText:"取消" //自定义取消按钮名称 }); } showAndActivateTabAct(sqdl_fid_value); } } else { showAndActivateTabAct(sqdl_fid_value); } } function showAndActivateTabAct(sqdl_fid_value) { switch(sqdl_fid_value) { case null: case "": jQuery("#tab_4").hide(); jQuery("#tab_5").hide(); jQuery("#tab_6").show().trigger('click'); break; case "0": jQuery("#tab_4").show().trigger('click'); jQuery("#tab_5").hide(); jQuery("#tab_6").hide(); break; case "1": jQuery("#tab_4").hide(); jQuery("#tab_5").show().trigger('click'); jQuery("#tab_6").hide(); break; default: console.warn("未知类别值:", sqdl_fid_value); break; } }
最新发布
08-28
### JavaScript 中 `toFixed` 的常见问题及解决方案 #### 1. **精度丢失** JavaScript 数字基于 IEEE 754 浮点数标准表示,这可能导致某些浮点运算的结果不精确。例如: ```javascript let num = 0.1 + 0.2; console.log(num); // 输出 0.30000000000000004 而不是预期的 0.3 ``` 如果直接调用 `num.toFixed(1)`,虽然会返回 `"0.3"`,但实际上这只是对显示层面上进行了处理,并未改变底层数值[^2]。 **解决方法:** 可以通过手动解析字符串并转换回数字的方式实现更精准的操作: ```javascript function fixFloat(number, digits) { return Number(Math.round(Number(number + 'e' + digits)) + 'e-' + digits); } let fixedNum = fixFloat(0.1 + 0.2, 1); console.log(fixedNum); // 正确输出 0.3 ``` --- #### 2. **不符合传统意义上的“四舍五入”逻辑** 尽管文档中提到 `toFixed()` 应该执行的是“四舍五入”,但在特定场景下它可能表现出异常行为。比如对于接近边界值的数据点可能会触发不同的取整规则[^1]。 考虑如下案例: ```javascript let n1 = 1.005; console.log(n1.toFixed(2)); // 可能输出 "1.00" ``` 这是因为内部算法遵循银行家舍入法(Banker's Rounding),也就是所谓的“四舍六入五成双”。这种策略倾向于减少累积误差,在统计学领域较为常用。 **解决方法:** 为了获得更加直观的传统意义下的“四舍五入”,可以自定义函数完成这一需求: ```javascript function customRound(value, decimals) { const factor = Math.pow(10, decimals); return (Math.round((value * factor) + Number.EPSILON) / factor).toFixed(decimals); } // 使用示例 console.log(customRound(1.005, 2)); // 输出 "1.01" ``` 上述代码通过引入极小量 (`Number.EPSILON`) 来规避潜在的小数位截断错误,从而确保最终结果符合常规理解中的“四舍五入”。 --- #### 3. **超出范围限制** `toFixed(digits)` 参数允许的最大值为 100 或最小值为 0。尝试设置超过此区间的参数将会抛出 RangeError 错误。 **解决方法:** 验证输入的有效性后再调用该方法即可避免此类异常发生: ```javascript function safeToFixed(num, digits) { if (digits < 0 || digits > 100) throw new Error('Invalid number of decimal places'); return num.toFixed(digits); } try { console.log(safeToFixed(123.456, -1)); } catch(e){ console.error(e.message); // Invalid number of decimal places } ``` --- #### 总结 通过对以上几种典型问题及其对应措施的学习可知,合理运用辅助工具以及深入理解其工作原理可以帮助开发者更好地掌控程序运行状态,进而提升应用质量与用户体验。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值