JS封装处理小数点精度问题

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        var floatObj = function () {

            /*
             * 判断obj是否为一个整数
             */
            function isInteger(obj) {
                return Math.floor(obj) === obj
            }

            /*
             * 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100
             * @param floatNum {number} 小数
             * @return {object}
             *   {times:100, num: 314}
             */
            function toInteger(floatNum) {
                var ret = { times: 1, num: 0 }
                if (isInteger(floatNum)) {
                    ret.num = floatNum
                    return ret
                }
                //转化为字符串
                var strfi = floatNum + ''
                //获取小数点的位置
                var dotPos = strfi.indexOf('.')
                //获取小数点后面的长度
                var len = strfi.substr(dotPos + 1).length
                //放大多少倍
                var times = Math.pow(10, len)
                //当前小数的整数 //小数点去掉的数字  0.1==>1
                var intNum = Number(floatNum.toString().replace('.', ''))
                //需要放大的倍数
                ret.times = times
                //小数点去掉的数字
                ret.num = intNum
                return ret
            }

            /*
             * 核心方法,实现加减乘除运算,确保不丢失精度
             * 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除)
             *
             * @param a {number} 运算数1
             * @param b {number} 运算数2
             * @param digits {number} 精度,保留的小数点数,比如 2, 即保留为两位小数
             * @param op {string} 运算类型,有加减乘除(add/subtract/multiply/divide)
             *
             */
            function operation(a, b, digits, op) {
                var o1 = toInteger(a)
                var o2 = toInteger(b)
                var n1 = o1.num
                var n2 = o2.num
                var t1 = o1.times
                var t2 = o2.times


                var max = t1 > t2 ? t1 : t2
                var result = null
                switch (op) {
                    case 'add':
                        if (t1 === t2) { // 两个小数位数相同
                            result = n1 + n2
                        } else if (t1 > t2) { // o1 小数位 大于 o2
                            result = n1 + n2 * (t1 / t2)
                        } else { // o1 小数位 小于 o2
                            result = n1 * (t2 / t1) + n2
                        }
                        return result / max
                    case 'subtract':
                        if (t1 === t2) {
                            result = n1 - n2
                        } else if (t1 > t2) {
                            result = n1 - n2 * (t1 / t2)
                        } else {
                            result = n1 * (t2 / t1) - n2
                        }
                        return result / max
                    case 'multiply':
                        result = (n1 * n2) / (t1 * t2)
                        return result
                    case 'divide':
                        result = (n1 / n2) * (t2 / t1)
                        return result
                }
            }

            // 加减乘除的四个接口
            function add(a, b, digits) {
                return operation(a, b, digits, 'add')
            }
            function subtract(a, b, digits) {
                return operation(a, b, digits, 'subtract')
            }
            function multiply(a, b, digits) {
                return operation(a, b, digits, 'multiply')
            }
            function divide(a, b, digits) {
                return operation(a, b, digits, 'divide')
            }

            // exports
            return {
                add: add,
                subtract: subtract,
                multiply: multiply,
                divide: divide
            }
        }();

        console.log(floatObj.add(0.4, 30.2))


    </script>
</head>

<body>

</body>

</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值