Problem specification
Today, the test sister came to me and said to me proudly that I found a bug of yours.
bug?
You’re kidding. How could the code I wrote have thatbug
This is absolutely impossible, even if there werebug
I will also secretly modify and then update, in my here is not existbug
.
Parse used json.parse to convert the ID to a different ID from the original ID, and then restored the bug in the local environment.
The diagram below:
The first thing that comes to mind when you see this is that you’re out of the safe integer range (real reaction: Holy crap, who made the ID that long?)
why
Js is in accordance with IEEE 754 specification, using double precision storage, occupying 64 bit, precision loss has a classic example
0.1+0.2! =0.3 / / true 0.30000000000000004
Copy the code
The problem is not just thatjs
It’s a problem in many languages, or any programming language that uses binary floating-point numbers, and you can also use this website0.30000000000000004.com/To see which languages have this problem. You can pass it at the front endmath.js
,decimal.js
Wait for the library to solve it.
The range of safe integers in js (that is, the range that can be safely used to perform arithmetic operations) can be obtained by MAX_SAFE_INTEGER and MIN_SAFE_INTEGER. Values outside this range are no longer accurate
console.log(Number.MAX_SAFE_INTEGER); / / 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); / / - 9007199254740991
Copy the code
Let me show you an example
let num1 = 90071992547409912342;
let num2 = 1111;
num1 + num2 = 90071992547409920000
Copy the code
The value of NUM1 is 90071992547409920000. The result is 90071992547409920000
The solution of the I
It’s also easy to fix the bug we found by converting numbers to strings, for example
var str = "{\ \" id ": 45361728384950273652, \" name \ ": \" front-end _ made uncle \ ", \ "url \" : \ "https://intolearn.com\"}";
var newStr = str.replace(/(\d{15,})/g.'" $1");
JSON.parse(newStr)
Copy the code
The maximum safe integer is 16 bits, so I’m just going to convert everything above 15 bits to a string, and it will display correctly