Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Day3 - Number() 的存储空间是多大?如果后台发送了一个超过最大限制的数字怎么办? #4

Open
su37josephxia opened this issue Dec 21, 2021 · 18 comments

Comments

@su37josephxia
Copy link
Owner

su37josephxia commented Dec 21, 2021

@moshuiyan
Copy link

2^1024到2^-1023
1.7976931348623157e+308,换算为10进制大概是179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858365。310位十进制。 如果后台发送超过这个数字,问问后台是不是故障了。要存储这个数字,很明显就不能直接使用number类型, 最简单的办法就是使用字符串类型或者BigInt

@bianzheCN
Copy link

bianzheCN commented Dec 25, 2021

存储空间(问 1)

最大 Number.MAX_VALUE2^1024

如果后台发送了一个超过最大限制的数字怎么办(问 2)

首先区分这个数字字符串是否需要运算

只需要 UI 展示

符合设计的话直接展示字符串,如果长度过长需要截取,找 PO 讨论。

需要计算

根据业务场景需要,决定是否需要前端计算,并分类讨论。

需要前端计算

对于需要即时得到交互结果的情况,优先让前端进行运算,我们用数字字符串的每一位进行计算,而不是转化为 Number.
最终可以根据业务去总结通用的工具函数,作为项目的 utils 使用。

后端运算

在需要运算的时候给后端发请求,参数带上操作数,让后端返回计算结果。

@MMmaXingXing
Copy link

存储空间

-2^53 + 1 ~ 2^53 - 1

如果后台发送了一个超限的数字

一、一般来说服务器必须将超限数字传输给前端则可以双方约定使用字符串类型来作为传输标准,其次作为需求接收方可以再复核一下对应需求是否合理。

二、前端来确认对应值是否需要计算,需要计算则前端采用BigInt来对超限字符进行处理,不需要计算则核对展示形式对应完成需求

@chunhuigao
Copy link

chunhuigao commented Dec 25, 2021

结论: 64 位双精度存储,最大精确值为2^53-1,超出这个值js不能精确表示

分类讨论

  • 确认需求,是否需要展示这么长的数据; 让服务端返回字符串;一般到这里这个问题就解决了
  • 接上一步,如果服务端不返回字符串,就返回数字;前端如何处理?
  • 使用第三方库,将数据转换成字符串,并向PD提前反馈超出部门不能精确表示,即使使用BigInt也不能精确表示

个人观点

  • 就前端而言,这么大的数据,对不需要给用户精确展示全部数据的场景,可以简略为科学技术法;
  • 如果是金钱,债劵等金融场景,确实需要精确展示所有数字,优先服务端返回精确值,其次使用第三方库,不允许适应第三方库,自己参考第三方库写一个方法,

bignumber结果

使用bignumber.js库。
输入 const bb = new BigNumber(123456789123456789123456789123456789)
输出:  {s: 1, e: 35, c: [12345678, 91234567800000]}
使用JavaScript写的第三方库也不能精确表示超出2^53-1的值

@rachern
Copy link

rachern commented Dec 25, 2021

Number的存储空间是 8 字节 64位,能精确存储 -(Math.pow(2, 53) - 1)) ~ Math.pow(2, 53)-1,超过这个范围的值也可以存储,但是会丢失精度

如果后台发送了一个超过最大限制的数字应该使用字符串的形式发送,前端根据情况对该字符串做处理

  1. 如果前端只是做数据的展示,那么直接使用字符串显示就可以
  2. 如果需要前端进行计算,前端可以把字符串转换成 BigInt 形式进行计算,但是 BigInt 和 Number 类型不可以混合计算,必须全部转化为 BigInt 在进行计算
  3. 不能转化为 BigInt 计算的,可以封装方法使用字符串按位计算,计算之后的结果再以字符串显示

@bianxuerui
Copy link

储存空间

Number() 的存储空间是 +-(Math.pow(2, 53) - 1);

如果数字超过最大限制

如果后台发送了一个超过最大限制的数字,js会发生截断,等于 JS 能支持的最大数字;
超过最大限制的数字可以和服务端约定返回字符串
如果这个字符串只需要展示的话,我们直接展示即可;
如果这个字符串需要计算的话,我们可以将其转换成array,补齐它们的长度,再一一相加得到一个新的数组;
最后再将新数组转换成数字;

@attackam
Copy link

attackam commented Dec 25, 2021

储存空间

最大存储空间是Number.MAX_VALUE = 2^1024,超过这个范围会被自动转成Infinity 。同时Number中要精确表示一个数字的话只能用Number.MAX_SAFE_INTEGER = 2^53 - 1 , 后面的位数全部自动转换成0。

如果数字超过最大限制

  1. 友好协商,如果单纯呈现,让后台把数字转成字符串即可;
  2. 如果涉及运算,可以通过js的BigInt类型来处理,但是记得BigInt不能跟Number进行运算,要把两个参数都转成BigInt,原文链接 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/BigInt;
  3. 如果要手工实现,可以转成数组的形式,我们可以分成1个数字一组,3个数字一组或者8个数字一组,这也是实现高精度运算比较常见的手段。

@qytayh
Copy link

qytayh commented Dec 25, 2021

存储空间

Number() 的存储空间是 2^53

如果后台发送了一个超过最大限制的数字怎么办?

表现 :会发生截断,等于 JS 能支持的最大数字

怎么办:与后端协商好通过字符串进行传输,如果前端是用来纯展示,那么直接用字符串来展示即可,如果要计算,可以先转为BigInt进行计算 然后通过toString转成字符串进行展示 注意:BigInt的计算只能与BigInt进行,需要将Number类型转成BigInt后进行计算

@yaoqq632319345
Copy link

Number 的存储空间在正负2^53-1之间,如果超出的话就会丢失准确性
如果后台发送了超过最大限制的数字,最好的办法就是转换为字符串,这样处理起来如果纯展示的话直接展示就可以,如果需要计算,也可以对字符串逐位进行计算,或者使用BigInt进行计算

@Limeijuan
Copy link

  • Number() 的存储空间

因为Javascript的数字存储使用了IEEE 754中规定的双精度浮点数数据类型,而这一数据类型能够安全存储 -(2^53 - 1) 到 2^53 - 1 之间的数值(包含边界值)

  • 如果后台发送了一个超过最大限制的数字

如果说在实际应用中遇到了超出最大限制的数字

可以让后台返回字符串

如果只是展示,那根据业务场景直接操作字符串,

-如果涉及到计算

可以使用BigInt操作

BigInt 可以表示任意大的整数,但是使用他时跟Number类型的混合运算,必须转成同种类型才可以;
并且BigInt转Number类型可能会丢失精度;

@jj56313751
Copy link

jj56313751 commented Dec 25, 2021

Number()的存储空间是多大?

  • 存储范围在2^-1023~2^1024
  • 因为数字是使用二进制64位浮点进行存储,指数位有11位即2048,值为0~2047,正负各一半,因此数值范围在2^-1023~2^1024
  • 数字大于等于2^1024正溢出返回Infinity
  • 数字小于等于2^-1075(指数部分最小值-1023,再加上小数部分的52位)负溢出返回0
  • 范围在-2^53~2^53之间的数字能够精准表示

如果后台发送了一个超过最大限制的数字怎么办

  • 如果超过了最大限制则无法表示,应该与后台进行协商,返回字符串类型

@jiafei-cat
Copy link

jiafei-cat commented Dec 25, 2021

在javascript当中Number的存储空间是64为比特位

  • 他的取值范围是正负2 ** 1023 * 1.999999999999999大小(超过这个数就是Infinity了),也就是Number.MAX_VALUE大小

后端返回了超过这个大小的数时(这里我们猜测返回两种类型)

  • 如果返回是string类型,而且我们只需要展示那展示即可,如果想要计算可以转bigInt计算,展示再转stirng即可
  • 如果返回的number类型,(我试着使用node返回超过最大数的数,因为都会转为Infinity,response表现为null,接着我又试着返回超过最大数的bigInt,node提示不能被JSON.stringify)因为bigInt都会被string后返回前端,所以这里猜测不会有超过最大数number类型的数到达前端,有知道的小伙伴可以给科普下。

@zhenyuWang
Copy link

存储空间

Number() 可以存储的
最小值是 Number.MIN_VALUE(5e-324)
最大值是 Number.MAX_VALUE(1.7976931348623157e+308)
最小安全整数是 Number.MIN_SAFE_INTEGER(-(Math.pow(2,53)-1))
最大安全整数是 Number.MAX_SAFE_INTEGER(Math.pow(2,53)-1)

解决方案

问题1. 如何传输?

后端发送给前端的时候把对应数值转为字符串传输或者使用json-bigint将接收到的超限数字转为字符串。

问题2. 只是展示

将转为字符串的数值直接展示即可

问题3. 需要计算

对字符串进行按位计算

@xyz-fish
Copy link

xyz-fish commented Dec 25, 2021

  • js number 存储空间是-Math.pow(2, 53) + 1 ~ Math.pow(2, 53) -1

    js number 类型是遵循IEE754的双精度浮点数的标准,占了64位内存空间,后52位是实际有效的数字。IEE754的标准规定第一位1是不存储在内存空间的, 所以存储空间方位应该是-Math.pow(2, 53) + 1 ~ Math.pow(2, 53) -1

  • 如果后台最大限制的数字怎么办,

    1. 先确定接口返回的是否有问题,一般不会出现超出限制的数字, 确定其是不是偶发性
    2. 只是展示的可以转成字符串进行展示
    3. 如果说我们需要处理超出限制的数字,根据实际情况,
      • 数字的分成多个数组进行返回和操作
      • 或者使用处理超精度数字的的库 bignumber.js
      • 在小于Number.MAX_VALUE的时候 通过科学计数法,也可以处理一些情况

@BambooSword
Copy link

Number() 的存储空间是多大?如果后台发送了一个超过最大限制的数字怎么办?
Number()的存储空间是Number.MIN_VALUE ~ Number.MAX_VALUE.不过一般这个最大值和最小值没有实际的意义,因为只要超过Number.MIN_SAFE_INTEGER~Number.MAX_SAFE_INTEGER就不能保证其数值的唯一确定性。
如果后台发送一个超过最大限制的数字(Number.MAX_SAFE_INTEGER)

  1. 若在前端直接接收,会显示为 Infinity,所以直接找后端,问清楚为什么要传过来这样的数字,这不是正常人类的操作,若是在有必要传这样的值,让其改成字符串类型。
  2. 若转成字符串后还要进行前端计算
    若是整数使用新增的 BigInt类型进行计算
    否则一定要使用有安全保障的库。特别注意不要随便用自己写的库就直接上线,除非是自己的玩具项目。

@liangle
Copy link

liangle commented Dec 25, 2021

  1. Number() 存储空间是64位,8字节。
  2. 如果后台返回超过最大限制的数字可以用bigint来计算,如果只是显示可以跟后端协商只返回字符串。

@JanusJiang1
Copy link

JanusJiang1 commented Dec 25, 2021

结论:

Number的最大储存空间可通过Number.MIN_VALUE ~ Number.MAX_VALUE获得
但实际最大安全范围为-(Math.pow(2,53)-1)~Math.pow(2,53)-1,超过会发生精度缺失

解决方法

先根据需求文档,判断这个数字出现是否合理,以及前端需要做什么处理,是否需要计算
若是合理必要,则与后台沟通需以字符串的方式进行传递
前台展示方面,如果还需要计算,则转化成bignit的方式进行计算
number转化为bigint,可通过构造函数或者在整数后面直接加n的方式实现
bigint计算主要需要注意两点,

  • 一是计算时需要将所有计算的项都转化为bigint,不能进行number和bigint的混合计算
  • 二是转化为bigint的数字不能传给web api的number相关函数作为参数处理,会报TypeError

@rhythm022
Copy link

rhythm022 commented Dec 25, 2021

Number的存储空间是由其科学计数法的11个指数位和52个有效数字位所决定的。比如Number的max_value就是在指数为1023,有效数字位二进制全为1的情况下所代表的数。而Number的min_value则是在指数为-1022,有效数字为除最后一位是二进制1,其余位全为0的情况下所代表的数。

我认为,如果后端返回的数已经超过了JS中的最大安全数,就应该以字符串的形式来表示该数。如果说需要做数值运算的话,应该使用BigInt类型,或者自己实现代码逻辑去直接处理数字字符串。

参考资料

探秘 JavaScript 世界的神秘数字 1.7976931348623157e+308

@su37josephxia su37josephxia changed the title Number() 的存储空间是多大?如果后台发送了一个超过最大限制的数字怎么办? Day3 - Number() 的存储空间是多大?如果后台发送了一个超过最大限制的数字怎么办? Jan 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests