产品经理:优惠金额只舍不入,支付金额只入不舍...

前言

当前做的项目是一个售卖会员的平台。其中涉及到优惠券、支付金额等。

优惠券分为:折扣券(n折)、抵扣券(减x元)

需求

优惠金额、支付金额都需要保留两位小数。
优惠金额 只舍不入,比如18.811元,显示为:18.82元。这样看起来,优惠的相对多一些
支付金额 只入不舍,比如18.888元,显示为:18.88元。

从产品角度来讲,这个设计相当人性化。

实现

js 复制代码
/**
 * 金额计算
 * @param {number} a sku原始价格
 * @param {number} b 优惠券金额/折扣
 * @param {string} mathFunc  四舍五入:round/ceil/floor 
 * @param {string} type  计算方式默认减法
 * @param {digits} type  精度,默认两位小数
 * */
export function numbleCalc(a, b,mathFunc='round', type = '-',digits=2) {

    var getDecimalLen = num =>{
        return num.toString().split('.')[1] ? num.toString().split('.')[1].length : 0;
    }

    var c;
    //获取2个数字中,最长的小数位数
    var aLen = getDecimalLen(a);
    var bLen = getDecimalLen(b);
    var decimalLen = aLen>bLen?aLen:bLen;
    var mul = decimalLen>0?(10 ** decimalLen):1;
    

    if(type=='-'){
         c = (a * mul - b*mul)/mul;
    }else if(type=='*'){
         c = (a*mul) * (b*mul)/mul/mul;
    }

    c  = digits==0?c : c * (10 ** digits);

    if(mathFunc=='floor'){
        c= Math.floor(c);
    }else if(mathFunc=='ceil'){
        c= Math.ceil(c);
    }else {
        c= Math.round(c);
    }
    return digits==0?c : c/(10**digits);
}

整体思路:获取两个数字之间最大的小数位,先取整再计算。 不直接进行计算,是因为存在0.1+0.2!=0.3的情况,具体原因可以看下文章下方的参考链接,写的很详细。

  • Math.ceil() 总是向上舍入,并返回大于等于给定数字的最小整数。
  • Math.floor() 函数总是返回小于等于一个给定数字的最大整数。
  • Math.round() 四舍五入

总结

封装的这个函数,只考虑了当前业务场景,未兼容一些边界值情况。

  • 大金额计算问题
  • 计算方式:加法、除法未做处理

参考

# 前端金额运算精度丢失问题及解决方案

相关推荐
乘风gg11 分钟前
多 Agent 不是万能的!搞懂这 5 个原则,少走 1 年弯路!
前端·agent·ai编程
猩猩程序员44 分钟前
Vercel 推出 Agent 框架 Eve:让 AI Agent 像写 Web 应用一样简单
前端
爱读源码的大都督1 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
爱勇宝1 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
小牛不牛的程序员1 小时前
我用 Claude Code 半天撸完了一个完整网站,AI 编程到底提升了多少效率?
前端
东风破_1 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript
ITOM运维行者2 小时前
从零搭建企业级服务器监控体系:踩坑实录与架构设计
前端·后端
monologues2 小时前
深入 Vue 3 源码:响应式系统的精妙设计与编译优化
前端
hunterandroid2 小时前
Paging 3 分页:从手动分页到声明式加载
前端
用户4099322502122 小时前
Vue状态管理入门第四章:组合式store和SSR风险
前端·vue.js·后端