Skip to content

数值计算

在前端的数值计算时,时常会遇到无法预料的问题,例如最常见的0.1+0.2≠0.3。为了尽可能减少可能曾遇见的问题,有必要记录下每种无法预料的情况是该怎么处理。

toFixed

将一个数字保留指定位数的小数

用法:

js
import { toFixed } from '@niu-tools/core/calcul'

toFixed(1.333332, 2)
// 1.33
import { toFixed } from '@niu-tools/core/calcul'

toFixed(1.333332, 2)
// 1.33
toFixed源码
ts
/**
 * 将一个数字保留指定位数的小数
 */
export function toFixed(number: any, m: any) {
    if (typeof number !== 'number') {
        throw new Error('number不是数字')
    }
    let result: any = Math.round(Math.pow(10, m) * number) / Math.pow(10, m)
    result = String(result)
    if (result.indexOf('.') == -1) {
        if (m != 0) {
            result += '.'
            result += new Array(m + 1).join('0')
        }
    } else {
        let arr = result.split('.')
        if (arr[1].length < m) {
            arr[1] += new Array(m - arr[1].length + 1).join('0')
        }
        result = arr.join('.')
    }
    return result
}
/**
 * 将一个数字保留指定位数的小数
 */
export function toFixed(number: any, m: any) {
    if (typeof number !== 'number') {
        throw new Error('number不是数字')
    }
    let result: any = Math.round(Math.pow(10, m) * number) / Math.pow(10, m)
    result = String(result)
    if (result.indexOf('.') == -1) {
        if (m != 0) {
            result += '.'
            result += new Array(m + 1).join('0')
        }
    } else {
        let arr = result.split('.')
        if (arr[1].length < m) {
            arr[1] += new Array(m - arr[1].length + 1).join('0')
        }
        result = arr.join('.')
    }
    return result
}

accAdd

两个数的精确相加

用法:

js
import { accAdd } from '@niu-tools/core/calcul'

accAdd(0.1, 0.2)
// 0.3
import { accAdd } from '@niu-tools/core/calcul'

accAdd(0.1, 0.2)
// 0.3
accAdd源码
ts
/**
 * 两个数的精确相加
 */
export function accAdd(arg1: any, arg2: any) {
    var r1
    var r2
    var m
    var c

    try {
        r1 = arg1.toString().split('.')[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split('.')[1].length
    } catch (e) {
        r2 = 0
    }
    c = Math.abs(r1 - r2)
    m = Math.pow(10, Math.max(r1, r2))
    if (c > 0) {
        var cm = Math.pow(10, c)
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace('.', ''))
            arg2 = Number(arg2.toString().replace('.', '')) * cm
        } else {
            arg1 = Number(arg1.toString().replace('.', '')) * cm
            arg2 = Number(arg2.toString().replace('.', ''))
        }
    } else {
        arg1 = Number(arg1.toString().replace('.', ''))
        arg2 = Number(arg2.toString().replace('.', ''))
    }
    return (arg1 + arg2) / m
}
/**
 * 两个数的精确相加
 */
export function accAdd(arg1: any, arg2: any) {
    var r1
    var r2
    var m
    var c

    try {
        r1 = arg1.toString().split('.')[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split('.')[1].length
    } catch (e) {
        r2 = 0
    }
    c = Math.abs(r1 - r2)
    m = Math.pow(10, Math.max(r1, r2))
    if (c > 0) {
        var cm = Math.pow(10, c)
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace('.', ''))
            arg2 = Number(arg2.toString().replace('.', '')) * cm
        } else {
            arg1 = Number(arg1.toString().replace('.', '')) * cm
            arg2 = Number(arg2.toString().replace('.', ''))
        }
    } else {
        arg1 = Number(arg1.toString().replace('.', ''))
        arg2 = Number(arg2.toString().replace('.', ''))
    }
    return (arg1 + arg2) / m
}

源码

查看源码
calcul/index.ts源码
ts
//toFixed===== Start
/**
 * 将一个数字保留指定位数的小数
 */
export function toFixed(number: any, m: any) {
    if (typeof number !== 'number') {
        throw new Error('number不是数字')
    }
    let result: any = Math.round(Math.pow(10, m) * number) / Math.pow(10, m)
    result = String(result)
    if (result.indexOf('.') == -1) {
        if (m != 0) {
            result += '.'
            result += new Array(m + 1).join('0')
        }
    } else {
        let arr = result.split('.')
        if (arr[1].length < m) {
            arr[1] += new Array(m - arr[1].length + 1).join('0')
        }
        result = arr.join('.')
    }
    return result
}
//toFixed===== End
//accAdd===== Start
/**
 * 两个数的精确相加
 */
export function accAdd(arg1: any, arg2: any) {
    var r1
    var r2
    var m
    var c

    try {
        r1 = arg1.toString().split('.')[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split('.')[1].length
    } catch (e) {
        r2 = 0
    }
    c = Math.abs(r1 - r2)
    m = Math.pow(10, Math.max(r1, r2))
    if (c > 0) {
        var cm = Math.pow(10, c)
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace('.', ''))
            arg2 = Number(arg2.toString().replace('.', '')) * cm
        } else {
            arg1 = Number(arg1.toString().replace('.', '')) * cm
            arg2 = Number(arg2.toString().replace('.', ''))
        }
    } else {
        arg1 = Number(arg1.toString().replace('.', ''))
        arg2 = Number(arg2.toString().replace('.', ''))
    }
    return (arg1 + arg2) / m
}
//accAdd===== End
//toFixed===== Start
/**
 * 将一个数字保留指定位数的小数
 */
export function toFixed(number: any, m: any) {
    if (typeof number !== 'number') {
        throw new Error('number不是数字')
    }
    let result: any = Math.round(Math.pow(10, m) * number) / Math.pow(10, m)
    result = String(result)
    if (result.indexOf('.') == -1) {
        if (m != 0) {
            result += '.'
            result += new Array(m + 1).join('0')
        }
    } else {
        let arr = result.split('.')
        if (arr[1].length < m) {
            arr[1] += new Array(m - arr[1].length + 1).join('0')
        }
        result = arr.join('.')
    }
    return result
}
//toFixed===== End
//accAdd===== Start
/**
 * 两个数的精确相加
 */
export function accAdd(arg1: any, arg2: any) {
    var r1
    var r2
    var m
    var c

    try {
        r1 = arg1.toString().split('.')[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split('.')[1].length
    } catch (e) {
        r2 = 0
    }
    c = Math.abs(r1 - r2)
    m = Math.pow(10, Math.max(r1, r2))
    if (c > 0) {
        var cm = Math.pow(10, c)
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace('.', ''))
            arg2 = Number(arg2.toString().replace('.', '')) * cm
        } else {
            arg1 = Number(arg1.toString().replace('.', '')) * cm
            arg2 = Number(arg2.toString().replace('.', ''))
        }
    } else {
        arg1 = Number(arg1.toString().replace('.', ''))
        arg2 = Number(arg2.toString().replace('.', ''))
    }
    return (arg1 + arg2) / m
}
//accAdd===== End

Released under the MIT License.