首页 > 其他分享 >高精度计算库math.js使用踩坑记

高精度计算库math.js使用踩坑记

时间:2024-10-19 19:32:57浏览次数:1  
标签:bignumber 坑记 押金 金额 js 扣款 total math deposit

前情

最近在做一个后端需求,需求中需要前端做一些金额数字计算,前端对于小数的计算一直都有精度问题,如0.1+0.2计算的结果并不是0.3,而是0.30000000000000004,于是引入高精度计算库math.js来解决前端计算的精度问题。

坑位

这次做的需求是一个退货扣款的需求,如果用户退回来的商品有磨损或者破坏需要进行扣除押金,但是扣除的金额不能超过押金,如果超过押金那就只能扣除押金的金额,开发中功能一切正常,测试也正常,但是一发布到线上发现无法正常工作,对于押金100的商品我想扣除50,正常来说扣款金额应该是50,但是实际显示扣款100,导致提交时和服务端计算的值进行校验不通过,以致始终无法完成数据提交,测试和我又立马回到测试服自测又是一切正常。

Why?

使用math.js转换或者计算方法计算完的值并不是数字,而是特有的BigNumber对象,当你直接拿对象比较的时候,它会调用对象的valueOf方法转换为字符串做比较,而字符串比较是按位比较大小的,所以‘50’跟’100’比,因为5>1所以’50’大于’100’,关键代码如下,为了好理解其中变量被替换成中文:

...
// 实际扣款金额 违约金+磨损扣款金额,不能大于押金
const actualDeductionAmount = computed(() => {
  let total = add(
    bignumber(违约金 || 0),
    bignumber(扣款金额 || 0)
  );
  let deposit = bignumber(押金金额 || 0);
  if (total > deposit) {
    total = deposit;
  }
  return format(total, { precision: 2, notation: "fixed" });
});
...

为什么测试服是好的了,是因为这种扣款是不可退回的,测一次自己要损失一笔钱,于是测试服配置的商品都是小于1的金额的,首位大小都是0,导致比较结果都是正确的,也就没有测试出来。
简单demo测试地址:JS Bin - Collaborative JavaScript Debugging

解决方案

在做比较时使用math.js提供的转数字方法number进行转换后再执行比较,保证数字与数字的比较就不会有问题。

...
// 实际扣款金额 违约金+磨损扣款金额,不能大于押金
const actualDeductionAmount = computed(() => {
  let total = add(
    bignumber(违约金 || 0),
    bignumber(扣款金额 || 0)
  );
  let deposit = bignumber(押金金额 || 0);
  if (number(total) > number(deposit)) {
    total = deposit;
  }
  return format(total, { precision: 2, notation: "fixed" });
});
...

思考

使用第三方工具库时要细看官方文挡,并确定你按收到的返回值是什么类型,此次使用前确实有浏览官方文挡的,但是个人英文真的很一般,不得不百度搜了一些使用教程,那些简易使用教程并没有明确说明返回的值类型,最近也在偶尔刷英语,希望能提高一些英语,对于程序员会英语还是很有帮助的,同时对于自测的时候应该多考虑一些边界值,此次测试都只测了小数金额而同有测整数,也导致问题一直拖到生产环境,幸好的是没有导致线上什么经济损失,不然就尴尬了。

标签:bignumber,坑记,押金,金额,js,扣款,total,math,deposit
From: https://www.cnblogs.com/xwwin/p/18481519

相关文章

  • js && jsx
    初始化useState是React的一个钩子(Hook),用于在函数组件中添加状态。currentTodoItem:当前输入框中的待办事项文本【字符串】。todoList:待办事项列表,包含多个【数组】待办事项对象。sortTodo这个函数用于比较两个待办事项,并决定它们的顺序。如果两个待办事项的完成状态不同,已完......
  • js查缺补漏——引用类型对象和数组
    一、什么是引用类型——Object引用类型是一种数据结构,而对象是引用类型的实例。有时候也叫对象定义,包含对象的属性和方法。Object是原生引用类型之一。创建对象实例的方法:1.使用new操作符varobj=newObject()obj.name="aaa"obj.age=122.使用对象字面量的......
  • 前端js html css 基础巩固4
    这是生成了不同的按钮进行显示 每一个按钮对应一个音频 点击按钮会播放对应的音频直接上代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0&qu......
  • “JsonConvert”同时存在于“Newtonsoft.Json.Net20, Version=3.5.0.0, Culture=neutr
    原因是两个dll冲突了。需要去掉一个。Newtonsoft.Json(也称为Json.NET)是一个流行的开源JSON框架,用于.NET,它以其高性能、易用性和广泛的功能而闻名。它支持丰富的数据操作和序列化属性设置,如自定义转换器、日期时间格式控制、命名策略等。Json.NET还提供了序列化特性,如JsonObjectA......
  • 基于Node.js+vue公司日常考勤系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于公司日常考勤系统的研究,现有研究主要集中在大型企业的整体人力资源管理系统中的考勤模块,专门针对中小型企业日常考勤系统独立开发与优化的研究较少......
  • 基于Node.js+vue化妆品配方及工艺管理系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于化妆品配方及工艺管理系统的研究,现有研究主要以化妆品的成分分析或单一功能模块(如配方设计)为主1,专门针对配方及工艺管理系统,整合用户、化妆品信息、......
  • 基于Node.js+vue个人记账服务系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于个人记账服务系统的研究,现有研究主要以企业财务管理系统为主,专门针对个人的记账服务系统研究较少。在国外,个人理财观念兴起较早,相关的个人财务管理......
  • 基于Node.js+vue翰明教育教学管理系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于教育教学管理系统的研究,现有研究主要以通用型的管理系统为主,专门针对翰明教育教学管理系统这种特定情境下的研究较少。在国内外,教育教学管理系统已......
  • Nuxt.js 应用中的 app:templatesGenerated 事件钩子详解
    title:Nuxt.js应用中的app:templatesGenerated事件钩子详解date:2024/10/19updated:2024/10/19author:cmdragonexcerpt:app:templatesGenerated是Nuxt.js的一个生命周期钩子,在模板编译到虚拟文件系统(VirtualFileSystem,VFS)之后被调用。这个钩子允许开发者在生......
  • jsp高校毕业生论文管理系统v3w2a
    jsp高校毕业生论文管理系统v3w2a本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能学生,院系管理员,论文信息,论文类型,论文成绩,下载记录,普通用户,院系名称,专业开题报告内容一、项目背景与意义在......