zoukankan      html  css  js  c++  java
  • TypeScript中处理大数字(会丢失后面部分数字)

    为啥要弄这玩意?

    最近做数值游戏,需要用到很大的数字,在前端大数字会自动变成e的科学计数法。

    例如123456789123456789123456789保存到localStorage时,会变成  1.2345678912345679e+26

    有啥问题?

    问题:

    1. 在传递给服务端时,服务端因为不能处理大数字(怎么就处理不了?!),就想要我传字符串给他,

        但是大数字会变成科学计数法的字符串"4e+23"之类给服务端,而不是"400000000000000..."理想的数字字符串。

    2. 在保存本地localStorage时,因为key-value的值只能是字符串,所以把num.toString()后也会变成科学计数法保存。

        例如123456789123456789123456789保存到localStorage时,会变成  1.2345678912345679e+26

    3. 尝试去github、csdn找BigDecimal之类的处理大数字的Javascript或Typescript版本,但是用不了。

    在常规H5里还好, 但是放到微信小游戏里就不行,会Decimal is not defined之类, 增加了window和修改wx.config配置文件也不行。急死个人哎。

    解决方案:

    1. 因为调试第三方库死活调不通,反正数值游戏在大数值以后,小数就非常微乎其微了,损失一些小数字也无所谓。而且项目急着上线,卧槽加班到很晚。

    2. 于是写了下面的一个很搓的方法。判断e的数量,来手动给数字字符串+"0"  = =!

    一个很搓的转换函数

        /**
         * 将数字转成字符串,可以转换超过16位的大数字,但是会丢失精度
         * @param value 数字
         */
        public getNumberToString(value: number) {
            let str = value.toString();
            //大于16位,用e表示的大数字,需要转换
            if (str.indexOf("e") != -1) {
                //e位置
                let eIndex = str.indexOf("e");
                //小数点位置
                let pIndex = str.indexOf(".");
                //是否有小数点, 400000000...这样的数是没有小数点的
                let bHavePoint = pIndex;
                //小数点位置
                pIndex = (pIndex == -1) ? 0 : pIndex;
                //小数点后的数字位数
                let small = eIndex - pIndex - 1;
                //e前面的数字
                let result = str.substr(0, eIndex);
                //如果e前面数字有小数点,则去掉小数点
                if (bHavePoint != -1) {
                    result = result.replace(".", "");
                }
                //e后面的数字
                let eNum = str.substr(eIndex + 2, str.length);
                //需要添加的0数量
                let len = parseInt(eNum) - small;
                for (let i = 0; i < len; i++) {
                    result += "0";
                }
                //返回最终结果
                return result;
            }else{
                //不是大数字,则直接返回
                return value.toString();
            }
    
        }
    

      

    实际应用

      protected createGameScene(): void {
            //小型数字,正确返回
            let a: number = 3000000;
            console.log(a.toString());               //3000000
            console.log(this.getNumberToString(a));  //3000000
    
            //大数字,后面数字有损
            let b:number = 123456789123456789123456789;   
            console.log(b.toString());               //1.2345678912345679e+26
            console.log(this.getNumberToString(b));  //123456789123456790000000000
    
            //大数字,无小数点,正确返回
            let c:number = 90000000000000000000000000000; 
            console.log(c.toString());               //9e+28
            console.log(this.getNumberToString(c));  //90000000000000000000000000000
            
            //大数字字符串 parseInt还原成 数字
            let d:number = parseInt(this.getNumberToString(c));
            console.log(d);  //9e+28
    
            //大数字字符串 parseFloat还原成 数字
            let e:number = parseFloat(this.getNumberToString(c));
            console.log(e);  //9e+28
    
            //科学计数法字符串  parseInt还原成数字  这里不能使用parseInt来还原科学计数法的字符串,会错误
            let f:number = parseInt(c.toString());
            console.log(f);  //9     
    
            //科学计数法字符串 parseFloat还原成数字 正确
            let g:number = parseFloat(c.toString());
            console.log(g);  //9e+28
        }
    
    

      

  • 相关阅读:
    python基础(set)补充
    运算
    初识正则表达式
    xml中俩种解析方式
    Android Studio 调用夜神模拟器
    Android Studio 配置虚拟设备的镜像文件的存放路径
    Allegro PCB Design GXL (legacy) 使用slide推挤走线,走线的宽度就发生改变的原因
    OrCAD Capture CIS 16.6 在原理图页面内放置图片
    OrCAD Capture CIS 16.6 修改原理图的页面大小
    ESD选型指南
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/9710966.html
Copyright © 2011-2022 走看看