自定义JS对数值操作的常用方法(通用四舍五入函数)

/**
 * 通用四舍五入函数
 * @param {string} type - 舍入类型,Enum('round', 'floor', 'ceil')
 * @param {number} value - 需要舍入的数值
 * @param {number} step - 舍入步长(单元)值
 * @example
 *    math.roundOff('round', 10.2, 0.5) // 10.0
 *    ath.roundOff('floor', 10.2, 0.5) // 10.0
 *    ath.roundOff('ceil', 10.2, 0.5) // 10.5
 * @returns {number}
 */
 var math;
math.roundOff = function (type, value, step) {
    const [stepBase, stepExp] = math.parseToExpPair(step);
    return math.safeExp10(Math[type](value / step) * stepBase, stepExp);
};

math.roundX = function (value, step) {
    return math.roundOff('round', value, step);
};
math.floorX = function (value, step) {
    return math.roundOff('floor', value, step);
};
math.ceilX = function (value, step) {
    return math.roundOff('ceil', value, step);
};

/**
 * 按数量级四舍五入
 * @param type
 * @param value
 * @param exp
 * @returns {number}
 */
math.decimalAdjust = function (type, value, exp) {
    if (value === undefined || value === null) return 0;
    if (isNaN(value)) return NaN;
    if (exp === undefined || exp === null || isNaN(Number(exp))) {
        exp = Math.floor(Math.log10(value)); // 使用自身的数量级
    }
    return math.safeExp10(Math[type](math.safeExp10(value, -exp)), exp);
};

/**
 * 根据数值自身的数量级四舍五入
 */
math.roundSelf10 = function (value) {
    return math.decimalAdjust('round', value);
};
/**
 * 根据数值自身的数量级向下舍
 */
math.floorSelf10 = function (value) {
    return math.decimalAdjust('round', value);
};
/**
 * 根据数值自身的数量级向上入
 */
math.ceilSelf10 = function (value) {
    return math.decimalAdjust('round', value);
};
/**
 * 使用科学记数法代替乘法来计算 10 的幂指数
 * @description
 *   使用 num * Math.pow() 的方法会存在浮点数精度问题,如 3 * Math.pow(10, -1) 会得到 0.30000000000000004
 *   使用科学记数法 3e-1 可以得到正常值 0.3
 * @param num
 * @param exp
 * @returns {number}
 */
math.safeExp10 = function (num, exp) {
    return Number(`${num}e${exp}`);
};

/**
 * 解析数值为科学记数法参数对
 * @param {number} num
 * @returns {null | number[]}
 */
math.parseToExpPair = function (num) {
    if (num === undefined) return null;
    var exp = Math.floor(Math.log10(num));
    var base = Number(`${num}e${-exp}`);
    return [base, exp];
};

/**
 * 安全地相对整数求余,返回科学记数法参数对
 * @param value
 * @param step
 * @returns {(number|*)[]}
 */
math.safeModIntToExpPair = function (value, step) {
    let [stepBase, stepExp] = math.parseToExpPair(step);
    stepBase = Math.floor(stepBase);
    const valueRelativeBase = math.safeExp10(value, -stepExp);
    const remainderExpPair = [valueRelativeBase % stepBase, stepExp];
    return remainderExpPair;
};

/**
 * 求取数值的数量级
 *
 * @example
 *      magOrder(1) // 0
 *      magOrder(1000) // 3
 *      magOrder(0.1) // -1
 * @param {number} value
 * @return {number}
 */
math.magOrder = function (value) {
    return Math.floor(Math.log10(value));
}

return math;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值