Java Long类型字段作为Response返回时给前端时会存在精度丢失的情况
现象:
在做ES查询接口调试的过程中,后端返回了某id字段,类型为Long类型,value为746733131538423809。在Postman中调试返回的response中始终只能看到746733131538423800。最后两位精度始终丢失。
原因:
Java Long类型和JavaSrcipt中的数字类型的精度范围不一致。
JavaScript内部只有一种数字类型Number,所有数字采用IEEE 754 标准定义的双精度64位格式存储,即使整数也是如此。
含义如下:
- 1位(s) 用来表示符号位,
0表示正数,1表示负数 - 11位(e) 用来表示指数部分
- 52位(f) 表示小数部分(即有效数字)
因为小数部分最大是52位,因此JavaScript中能精准表示的最大整数是2^53-1,十进制为9007199254740991。
不在这个范围的数叫做不安全整数,不安全整数可能会导致精度丢失。
console.log(Number.MAX_SAFE_INTEGER + 1); // 结果:9007199254740992,精度未丢失
console.log(Number.MAX_SAFE_INTEGER + 2); // 结果:9007199254740992,精度丢失
console.log(Number.MAX_SAFE_INTEGER + 3); // 结果:9007199254740994,精度未丢失
console.log(Number.MAX_SAFE_INTEGER + 4); // 结果:9007199254740996,精度丢失
console.log(Number.MAX_SAFE_INTEGER + 5); // 结果:9007199254740996,精度未丢失
而我之前传的值746733131538423809已经远远大于了Number.MAX_SAFE_INTEGER,只要超过Number.MAX_SAFE_INTEGER,就有可能产生精度丢失,从而导致数据和逻辑出错的情况。
后端开发人员应该怎么做?
在给出到前端的锲约中,不要给Long类型的字段,可以用String代替。