• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

TypeScript中处理大数字(会丢失后面部分数字)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

为啥要弄这玩意?

最近做数值游戏,需要用到很大的数字,在前端大数字会自动变成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
    }

  


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
vue-cli3+typescript+router发布时间:2022-07-18
下一篇:
开发并发布npm包,支持TypeScript提示,rollup构建打包发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap