Weird Behaviour in JS Explained: Math.min() > Math.max()

Javascript is indeed a great language. But at times it is tricky, funny, behaves weirdly and, what-not.
One Such weird fact is,

But how?
Let me explain.
First let us understand what Math.min() and Math.max() functions are.
Math.min(): When Zero or more arguments are passed, it returns the smallest of the values orNaNif any parameter isn't a number or can't be converted into one.
Examples,

Math.max(): When Zero or more arguments are passed, it returns the largest of the values orNaNif any parameter isn't a number or can't be converted into one.
Examples,

So What happens when there is zero arguments to theMath.min() and Math.max() functions.

The Math.max() function returns -Infinity while the Math.min() function returns +Infinity
Why this weird behavior?
To know about it we need to look into the internal implementation of its algorithm
Internal Implementation of the algorithm
According to TC39 - Where Javascript Standard (ECMAScript) is defined, Math.min() and Math.max() the smallest or largest respectively is determined using IsLessThan algorithm is used except when +0 and -0 comparison is involved where +0 is the largest.
The Pseudocode or the steps as defined by TC39, in a pure Javascript function form:
function minimum(...args) {
let temp = [];
let smallest = Infinity;
for(let i=0; i<args.length; i++) {
temp.push(Number(args[i])); //
}
for (let i = 0; i < temp.length; i++) {
if(temp[i].isNaN()) {
return temp[i];
}
if(temp[i] < smallest) {
smallest = temp[i];
}
}
return smallest;
}
function maximum(...args) {
let temp = [];
let largest = -Infinity;
for(let i=0; i<args.length; i++) {
temp.push(Number(args[i]));
}
for (let i = 0; i < temp.length; i++) {
if(temp[i].isNaN()) {
return temp[i];
}
if(largest < temp[i] {
largest = temp[i];
}
}
return largest;
}
console.log(minimum(99,'2',3, -54)); // -54
console.log(maximum(99,'2',3, -54)); // 99
console.log(minimum(true, '45', -22, 0, 1999)); // -22
console.log(maximum(true, '45', -22, 0, 1999)); // 1999
console.log(minimum(true, false)); // 0
console.log(maximum(true, false)); // 1
console.log(minimum()); // Infinity
console.log(maximum()); // -Infinity
Let us walk through the above code.
Math.min() function - minimum()
- When zero or more arguments which form the rest parameter
...args - Let
tempbe a temporary array, which is used for type conversion. - Let
smallest, the initial comparant, beInfinityas IsLessThan algorithm is used and almost every other value is smaller - Now all the values in the
argsare checked for theNumbertype, if not, they will be converted toNumberand appended to the temp array. The below table gives an overall idea of this conversion.
| Type | Return Result |
| Undefined | Return NaN. |
| Null | Return +0. |
| Boolean | If true, return 1. If false, return +0. |
| Number | Return as such (no conversion). |
| String | If there is a Number within String, returns the number else returns NaN. |
| Symbol | Throw a TypeError exception. |
| BigInt | Throw a TypeError exception. |
- Now if there is any
NaN, then the function returnsNaN. Else it compares the whole array with thesmallestand returns the smallest number.
Math.max() function - maximum()
All steps are repeated for Math.max(), except the initial Comparant is set to -Infinity and almost every other value is larger.
So the Math.min() and Math.max() with zero values passed, returns Infinity & -Infinity respectively attributing to the weird behaviour we had seen before, Math.Min() is greater than Math.min().
Also, check the V8 implementation of Math.min() & Math.max() can be found at this github repo.
If I have missed any points, please let me know in the comments.






