今天和前端联调接口发现一个神奇的问题后端返回的id值和前端取到的居然不一样。
在chrome浏览器中观看到的内容,
在预览和相应里面展示的内容居然也不一样。
JS解析Long类型失真
JavaScript中的数据都是Number类型使用的是这种标准存储的, IEEE-754 存储
JavaScript中的数据都是Number类型,Number对于数字的精度是优先的,java中的类型已经超过了js的处理范围。 js中Number类型使用8字节64位表示,占用的空间和java中long类型一样,但是js中number类型的结构如下
| s | eeeeeee eeee | ffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff |
|---|
1 11 52
各位的含义
- 1位 (s) 用来表示符号位, 0正数 1负数
- 11位 (e) 用来表示指数部分
- 52位 (f)表示小数部分,也就是有效数字
也就是说Number类型最大最小的数字 分别如下
max = Math.pow(2, 53) - 1;
min = Math.pow(-2, 53);
Java中long类型最大长度
| s | fffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff |
|---|
1 63
max = Math.pow(2, 63) - 1;
min = Math.pow(-2, 63);
@Test
public void t2() {
System.out.println(Long.MAX_VALUE);
System.out.println((long) (Math.pow(2, 63) - 1));
System.out.println(Long.MIN_VALUE);
System.out.println((long) Math.pow(-2, 63));
}
/////
9223372036854775807
9223372036854775807
-9223372036854775808
-9223372036854775808
结论
Java中的long类型可表示的最大数字远远大于js中的Number,所以一旦接口返回的数据大于 9007199254740991或者小于 -9007199254740991
就会出现js数字失真的问题。
解决方案
将接口返回的long类型转换成String就行,json兼容这类处理。