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类型添加一个格式化方法,比如叫 ...
随机推荐
- hive 添加自增列
比如一个表里只有contact字段 ;
- sql server 2014 序列號
亲测可用 27HMJ-GH7P9-X2TTB-WPHQC-RG79R
- linux中显示有颜色的字符
https://blog.csdn.net/weixin_42867972/article/details/81700469 # 设置命令提示符 PS1="\033[33;1m[\033[3 ...
- [原]unity3D 移动平台崩溃信息收集
http://m.blog.csdn.net/blog/catandrat111/8534287http://m.blog.csdn.net/blog/catandrat111/8534287
- 架构设计:系统存储(28)——分布式文件系统Ceph(挂载)
(接上文<架构设计:系统存储(27)--分布式文件系统Ceph(安装)>) 3. 连接到Ceph系统 3-1. 连接客户端 完毕Ceph文件系统的创建过程后.就能够让客户端连接过去. Ce ...
- POJ1159——Palindrome
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 53647 Accepted: 18522 Desc ...
- vuejs中使用echart图表
首先安装echart npm i echarts -S 加下来以使用这个图表为例 在vue组件中像这样使用: <template> <div :class="classNa ...
- Unity Shader 获取模型空间坐标
CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma ...
- It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing ___Error Installing APK
一 : 根据以下路径,找到Instant Run中的选项 File —— Settings——Build,Execution,Deployment——Instant Run ...
- mysql的存储过程与事务入门
存储过程是:通过一系列的SQL语句, 根据传入的参数(也可以没有), 通过简单的调用, 完成比单个SQL语句更复杂的功能, 存储在数据库服务器端,只需要编译过一次之后再次使用都不需要再进行编译.主要对 ...