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
}
TypeScript中处理大数字(会丢失后面部分数字)的更多相关文章
- 使用千位分隔符(逗号)表示web网页中的大数字
做手机端页面我们常常遇到数字,而在Safari浏览器下这些数字会默认显示电话号码,于是我们就用到了补坑的方法加入<meta>标签: <meta name="format-d ...
- JavaScript数字精度丢失问题总结
本文分为三个部分 JS 数字精度丢失的一些典型问题 JS 数字精度丢失的原因 解决方案(一个对象+一个函数) 一.JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加 0.1 + 0.2 != ...
- TypeScript 中的方法重载
方法重载(overload)在传统的静态类型语言中是很常见的.JavaScript 作为动态语言, 是没有重载这一说的.一是它的参数没有类型的区分,二是对参数个数也没有检查.虽然语言层面无法自动进行重 ...
- JavaScript数字精度丢失的一些问题
本文分为三个部分 JS 数字精度丢失的一些典型问题 JS 数字精度丢失的原因 解决方案(一个对象+一个函数) 一.JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加 1 0.1 + 0.2 ! ...
- java学习第13天( java获取当前时间,有关大数据的运算及精确数字运算,Date类)
一 java获取当前时间 学习一个函数,得到当前时间的准确值 System.currectTimeMillis(). 可以得到以毫秒为单位的当前时间.它主要用于计算程序运行时间,long start= ...
- android 自定义adapter和线程结合 + ListView中按钮滑动后状态丢失解决办法
adapter+线程 1.很多时候自定义adapter的数据都是来源于服务器的,所以在获取服务器的时候就需要异步获取,这里就需要开线程了(线程池)去获取服务器的数据了.但这样有的时候adapter的中 ...
- php导出CSV时,超长数字精度丢失问题与前导0的字符串丢失0的问题解决
php生成的CSV有时候会遇到两个特殊情况: 1.输出的字段中,含有超长数字(18位的数字)比方身份证:122121197410180016,就算输出时字段加上"",还是会被识别成 ...
- 面试题解:输入一个数A,找到大于A的一个最小数B,且B中不存在连续相等的两个数字
玄魂工作室秘书 [玄魂工作室] 昨天发的算法有一处情况没考虑到,比如加一后有进位,导致又出现重复数字的情况,修正后今天重新发一次. 比如输入99,那B应该是101 因为100有两个连 ...
- 在TypeScript中扩展JavaScript基础对象的功能
最近工作中用到,记录一下:假设我们需要一个功能,把一个数字比如10000输出为下面的字符串格式“10,000”,一般是写一个方法,那么我希望更方便一点,直接向Number类型添加一个格式化方法,比如叫 ...
随机推荐
- middle源码
CREATE TABLE `middle` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `innserSessionid` VARCHAR(250 ...
- 【WP8】键盘弹出时控制Frame位置
WP上,当使用TextBox输入文字的时候,键盘会把TextBox向上推一段距离 当编辑第二个TextBox的时候,页面被上推,键盘刚好和TextBox靠在一起 当编辑第一个TextBox的时候,页面 ...
- java中substring的用法
substring 1.public String substring(int beginIndex). 返回一个新的字符串,它是此字符串的一个子字符串.该子字符串始于指定索引处的字符,一直到 ...
- 中企ITIL需软落地
IT技术的发展对现代企业产生了深远的影响.企业信息化建设越深入,信息系统的规模越大,业务对IT系统的依赖性也越大,由此对IT服务的要求越高,如何 对繁多的IT技术进行有效的管理,最大程度地利用企业现有 ...
- 【乐呵一下】WINDOWS有个非常低级的错误!
该错误来自微软windows附带的计算器(开始附件计算器). 1. 当你尝试用9216除以96并按下=按钮时,计算器竟然没有反应!!! 而9216除以97,98却正常. 2. 还有一个错误,当你尝试用 ...
- Innodb表压缩过程中遇到的坑(innodb_file_format)
https://www.cnblogs.com/billyxp/p/3342969.html
- MongoDB使用经验总结
摘要: 最近在开发项目使用了数据库MongoDB,我将它的使用方法整理下分享给大家.至于mongoDB有什么优点,大家可以到官网去看. 安装: 首先我们需要到官网下载适合自己系统的mongodb. w ...
- Python基础教程学习笔记:第一章 基础知识
Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入“p ...
- Spring踩坑记录
1. Spring properties配置项不能解析问题 本地部分配置文件迁到disconf,希望disconf的配置文件交由spring托管.这样的话,原有代码中引用配置的地方就不用变(还是用${ ...
- WinInet API详解
一.概述 WinInet(「Windows Internet」)API帮助程序员使用三个常见的Internet协议,这三个协议是:用于World Wide Web万维网的超文本传输协议(HTTP:Hy ...