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 thatbugThis is absolutely impossible, even if there werebugI 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 thatjsIt’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.jsWait 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