Start with an interview question that can change love.
Last week, my team fairy gave me an interview question, the topic is: under what circumstances, A === A-1.
I don’t know who the specific source of this question is, but as a veteran immersed in the front for many years, this kind of question is naturally difficult to me.
Of course, this question is not difficult, many students should be able to tell an answer at the first feeling, but how many answers to this question? Can you give me more answers, maybe infinitely more answers?
Think for 10 seconds and then look down
The first answer, of course, is Infinity, or, by extension, plus or minus Infinity.
👉🏻 In JavaScript, Infinity is a literal of type Number, representing Infinity. When a value of type Number exceeds the maximum value that can be represented during an operation, infinity occurs.
For example, if we divide a positive number that is not 0 by 0, we get infinity.
console.log(100 / 0); // Infinity
Copy the code
Correspondingly, negative numbers have negative infinity.
console.log(-100 / 0); // -Infinity
Copy the code
If we go beyond what Number allows us to represent, we’ll get Infinity.
console.log(1e1000); // Infinity
Copy the code
POSITIVE_INFINITY and Number.NEGATIVE_INFINITY correspond to Infinity and Infinity in JavaScript.
Number.isfinite (n) specifies whether a Number isFinite. If n is of type Number, return false only if it is Infinity or NaN, otherwise return true.
Any finite number plus or minus Infinity is Infinity, and Infinity === Infinity, so:
let a = Infinity;
console.log(a === a - 1); // true
let b = -Infinity;
console.log(b === b - 1); // true
Copy the code
So we have two answers.
💡 However, note that the result of an Infinity operation is not always Infinity. For example, let’s look at the following operations:
console.log(Infinity + Infinity); // Infinity
console.log(Infinity - Infinity); // NaN
console.log(Infinity * Infinity); // Infinity
console.log(Infinity / Infinity); // NaN
console.log(Infinity * 0); // NaN
Copy the code
The conclusion is that Infinity can also lead to NaN, so you need to be careful. For example, if we have an expression that has two values multiplied together, one of which may be large and the other may be zero, you need to be careful. If that large value is worth Infinity and the other value happens to be zero, The value of the entire expression can be NaN, which can cause some bugs.
const result = a + b * c + d; // If b is Infinity and c is 0, the result of the whole expression may be NaNCopy the code
Ok, so that’s our first answer: plus or minus Infinity.
Next, let’s look at another (other) answer.
Let’s give a a large number, like 1e45:
let a = 1e45;
console.log(a); // 1e+45
console.log(a === a - 1); // true
Copy the code
Some students a look, ah, this is also ok?
Not only does this work, but if you pick any two large numbers, it should work:
Let a = 6.22 electronics; console.log(a === a - 1); // trueCopy the code
So what’s going on here?
👉🏻 In JavaScript, integers can be accurately represented in the range from -2 ** 53 + 1 to 2 ** 53-1, namely -9007199254740991 to 9007199254740991. Any integer above this value cannot be accurately represented.
The constants Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER correspond to 9007199254740991 and -9007199254740991 respectively.
Let’s test it out:
let a = 9007199254740986;
for(let i = 0; i < 10; i++) {
console.log(`${i} : ${a + i}`);
}
Copy the code
The output in Chrome looks like this:
0:9007199254740986 1:9007199254740987 2:9007199254740988 3:9007199254740989 4:9007199254740990 5:9007199254740990 9007199254740991 6:9007199254740992 7:9007199254740992 8:9007199254740994 9:9007199254740996Copy the code
When the value of A + I is less than or equal to 9007199254740991, the output normally increases by 1 each time. When the value is greater than 9007199254740991, the output results appear 9007199254740992 twice. There are 9007199254740993 and 9007199254740995 missing. This is because, after 9007199254740991, JavaScript’s Number type is no longer able to accurately represent integers. Because the accuracy is lost, 9007199254740993 and 9007199254740995 are missing.
We can use this knowledge to construct other values that satisfy our requirements:
let a = Number.MIN_SAFE_INTEGER - 1;
console.log(a === a - 1); // true
Copy the code
Big Integer Big Integer
The TC39 Big Integer proposal is currently in Stage 3 and is already supported in Chrome.
console.log(2 ** 2000); // Infinity console.log(2n ** 2000n); // 114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277 344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026 040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002 716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672 039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029 376nCopy the code
NaN
Some of you might think of NaN, but NaN is not equal to any value, including NaN itself, so using NaN is not possible:
let a = NaN;
console.log(a === a - 1); // false
Copy the code
Finally, if the interview question is not a === A-1, but a == A-1, what are the other answers? Think about it and discuss it under Github Issue.