老板:你工作5年了,为什么还会犯这个简单的错误?
这个错误的描述
这个问题可能是这样的。
莉莉在公司负责一个重大的项目,其中一个模块就是显示一个数字相关的信息。
这是后端工程师接口返回的信息(只是举例)
@RestController
@RequestMapping("/getInfo")
public class YupiTestController {
@GetMapping
public Long getNum() {
return 123456789123456789L;
}
}小伙伴们,我们调用接口会返回什么信息呢getInfo?会吗123456789123456789?

通过chrome浏览器的调试工具可以看到,好像一切都和我们想的结果一样123456789123456789。
但是页面显示的结果是123456789123456780,最后一位是0而不是9

这到底是怎么回事?这太奇怪了。
原因分析
我试着分析返回的数字,发现最后几位不一致的问题只有在数字超过16位时才会出现。
是不是因为数字太大,出现了精度损失?语言中的 Long 类型Java是 64 位,语言Long中的类型JavaScript是否小于 64 位?
我的天啊,JavaScript似乎没有类型的数据Long!
实际上,在 中JavaScript,我们使用一个 Number 来表示类型数字的值。
Number 类型的总长度为 64 位。64位大致是这样分配的,其中53位代表小数位,10位代表指数位,1位代表符号位。因此,Number 整数的表示范围为-2^53 ~ 2^53。
让我们尝试在控制台上用 JavaScript 打印出最大值和最小值。

在其他语言中,比如Java,Long类型占用64个二进制位,最大值为9223372036854774807(²⁶³ — 1),长度约为19位。
在 中JavaScript,由于 Number 类型的值也包含小数,因此最大值为 9007199254740993 (2^53 - 1),长度约为 16 位。
所以当Java返回超过16位的Long类型字段给JSON时,前端JavaScript获取的数据会因为溢出而失去精度。

如何解决这个问题呢?
或许我们可以尝试在前端解决这个问题,但我觉得还是应该寻求后端工程师的帮助。
我们应该将可能超出范围的数值类型(Long)变量转换为字符串类型(String)。
翻译来自:https://fatfish.medium.com/my-boss-you-have-been-working-for-5-years-but-why-do-you-still-make-this-simple-mistake-8db286b00aef
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!