大数字的单位转换方法

8 篇文章 0 订阅
5 篇文章 0 订阅


近期做了个游戏,用到了大数字的单位计算和转换,这里作为参考纪录一下。js写的,其他的语言应该也差不了太多。

数据准备

显示的通用格式为: 999.999aa,小于7位数则显示:999,999,小于4位数则显示: 999.999
用于计算的大数字类使用得是:https://github.com/MikeMcl/decimal.js

UNIT_BASE: ["", "", "M", "B", "T"],
UNIT_CHAT: [
        "a", "b", "c", "d", "e", "f", "g",
        "h", "i", "j", "k", "l", "m", "n",
        "o", "p", "q", "r", "s", "t",
        "u", "v", "w", "x", "y", "z"],

大数字转字符串

    /**
     * 将大数字转换为带单位的6位长度数字
     * @public
     * @see https://github.com/MikeMcl/decimal.js/
     * @param {Decimal} _val 
     * @returns {String}
     */
    decimal2string(_val) {
        if (!(_val instanceof Decimal)) {
            _val = new Decimal(_val);
        }
        let neg = _val.isNeg();
        if (neg) _val = _val.abs();
        let n = _val;
        let e = n.e;
        let m = e / 3;
        if (e % 3 != 0) {
            m = Math.floor((e - 1) / 3);
            e = m * 3;
            if (e < 0) e = 0;
        }
        if (m < 0) m = 0;
        let str = "";
        let unit = "";
        if (e < 15) {
            unit = this.UNIT_BASE[m];
        } else {
            let n = Math.floor((e - 15) / 3);
            unit = "";
            if (n < 26) {
                unit = this.UNIT_CHAT[0] + this.UNIT_CHAT[n];
            } else {
                while (n > 0) {
                    let r = n % 26;
                    n = Math.floor(n / 26);
                    unit = this.UNIT_CHAT[r] + unit;
                }
            }
        }
        if (n.lt(1000)) {
            str = n.toFixed(3).toString();
            if (str.indexOf(".") != -1) {
                while (str.charAt(str.length - 1) == "0") {
                    str = str.slice(0, str.length - 1);
                }
            }
            if (str.charAt(str.length - 1) == ".") {
                str = str.slice(0, str.length - 1);
            }
        } else if (n.lt(1000000)) {
            str = n.toDP(0).toString();
            let ins = str.length - 3;
            str = str.slice(0, ins) + "," + str.slice(ins);
        } else {
            let n0 = n.div(Decimal.pow(1000, m)).toFixed(3);
            str = n0.toString();
            if (str.indexOf(".") != -1) {
                while (str.charAt(str.length - 1) == "0") {
                    str = str.slice(0, str.length - 1);
                }
            }
            if (str.charAt(str.length - 1) == ".") {
                str = str.slice(0, str.length - 1);
            }
        }
        return (neg ? "-" : "") + str + unit;
    },

字符串转大数字

    /**
     * 将字符串转为大数字, 格式为 10, "10", "10|T"
     * @public
     * @see https://github.com/MikeMcl/decimal.js/
     * @param {Number||String} _val 
     * @returns {Decimal}
     */
    string2decimal(_str) {
        let num;
        if (_str instanceof Decimal) {
            return _str;
        }
        _str = "" + _str;
        if (typeof _str == 'number') {
            num = new Decimal(_str);
            // debug( "NumberUtils.string2decimal: number->" + num.toString() );
            return num;
        }
        if (_str.indexOf("|") == -1) {
            num = new Decimal(_str);
            // debug( "NumberUtils.string2decimal: string->" + num.toString() );
            return num;
        }

        let str = _str.split("|");
        let m = 0;
        let x = parseFloat(str[0]);
        if (this._units == null) {
            this._units = new Map();
            let cfgs = C.all("GameUnit");
            for (let cfg of cfgs) {
                this._units.set(cfg[1].unit, cfg[0]);
            }
        }
        if (this._units.has(str[1])) {
            m = this._units.get(str[1]);
        }
        num = Decimal.pow(10, m).times(x);
        // debug( "NumberUtils.string2decimal: -->" + num.toString() );
        return num;
    },

说明

以上内容没有经验严格测试,属于能用的阶段吧。至少目前为止没有出现问题。
最后附上源代码地址:https://github.com/aiyoyoyo/CocosCreator-Jees/blob/master/src/jees-util.js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值