在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
为啥要弄这玩意?最近做数值游戏,需要用到很大的数字,在前端大数字会自动变成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 }
|
请发表评论