How does Javascript Math.max and Math.min work?

I'm really curious how these features really work? I know that there are many questions about how to use them, I already know how to use them, but I could not find anywhere how to actually implement this function in an array, for example, if there were no such functions? How would you code such a function if there were no helpers?

+5
source share
6 answers

Let's look at the specifications (which could / should have helped you with the implementation!)

In ECMAScript 1st Edition (ECMA-262) (initial definitions for Math.max / min), we see the following:

15.8.2.11 max(x, y) Returns the larger of the two arguments. โ€ข If either argument is NaN, the result is NaN. โ€ข If x>y, the result is x. โ€ข If y>x, the result is y. โ€ข If x is +0 and y is +0, the result is +0. โ€ข If x is +0 and y is โˆ’0, the result is +0. โ€ข If x is โˆ’0 and y is +0, the result is +0. โ€ข If x is โˆ’0 and y is โˆ’0, the result is โˆ’0. 15.8.2.12 min(x, y) Returns the smaller of the two arguments. โ€ข If either argument is NaN, the result is NaN. โ€ข If x<y, the result is x. โ€ข If y<x, the result is y. โ€ข If x is +0 and y is +0, the result is +0. โ€ข If x is +0 and y is โˆ’0, the result is โˆ’0. โ€ข If x is โˆ’0 and y is +0, the result is โˆ’0. โ€ข If x is โˆ’0 and y is โˆ’0, the result is โˆ’0. 

Later versions of the specification give us:

ECMAScript 5.1

 15.8.2.11 max ( [ value1 [ , value2 [ , โ€ฆ ] ] ] ) Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values. โ€ข If no arguments are given, the result is โˆ’โˆž. โ€ข If any value is NaN, the result is NaN. โ€ข The comparison of values to determine the largest value is done as in 11.8.5 except that +0 is considered to be larger than โˆ’0. The length property of the max method is 2. 15.8.2.12 min ( [ value1 [ , value2 [ , โ€ฆ ] ] ] ) Given zero or more arguments, calls ToNumber on each of the arguments and returns the smallest of the resulting values. โ€ข If no arguments are given, the result is +โˆž. โ€ข If any value is NaN, the result is NaN. โ€ข The comparison of values to determine the smallest value is done as in 11.8.5 except that +0 is considered to be larger than โˆ’0. The length property of the min method is 2. 

Link to 11.8.5 is given here: Abstract Relational Comparison Algorithm

ECMAScript 2015

 20.2.2.24 Math.max ( value1, value2 , โ€ฆvalues ) Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values. โ€ข If no arguments are given, the result is โˆ’โˆž. โ€ข If any value is NaN, the result is NaN. โ€ข The comparison of values to determine the largest value is done using the Abstract Relational Comparison algorithm (7.2.11) except that +0 is considered to be larger than โˆ’0. The length property of the max method is 2. 20.2.2.25 Math.min ( value1, value2 , โ€ฆvalues ) Given zero or more arguments, calls ToNumber on each of the arguments and returns the smallest of the resulting values. โ€ข If no arguments are given, the result is +โˆž. โ€ข If any value is NaN, the result is NaN. โ€ข The comparison of values to determine the smallest value is done using the Abstract Relational Comparison algorithm (7.2.11) except that +0 is considered to be larger than โˆ’0. The length property of the min method is 2. 

Again 7.2.11 can be found here: Abstract relational comparison

+3
source

Here is the Math.max code in Chrome V8.

 function MathMax(arg1, arg2) { // length == 2 var length = %_ArgumentsLength(); if (length == 2) { arg1 = TO_NUMBER(arg1); arg2 = TO_NUMBER(arg2); if (arg2 > arg1) return arg2; if (arg1 > arg2) return arg1; if (arg1 == arg2) { // Make sure -0 is considered less than +0. return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg2 : arg1; } // All comparisons failed, one of the arguments must be NaN. return NaN; } var r = -INFINITY; for (var i = 0; i < length; i++) { var n = %_Arguments(i); n = TO_NUMBER(n); // Make sure +0 is considered greater than -0. if (NUMBER_IS_NAN(n) || n > r || (r === 0 && n === 0 && %_IsMinusZero(r))) { r = n; } } return r; } 

Here is the repository.

+2
source

The following describes how to implement functions if Math.min() and Math.max() did not exist.

Functions have an arguments object that you can iterate to get your values.

It is important to note that Math.min() without arguments returns Infinity and Math.max() without arguments returns -Infinity .

 function min() { var result= Infinity; for(var i in arguments) { if(arguments[i] < result) { result = arguments[i]; } } return result; } function max() { var result= -Infinity; for(var i in arguments) { if(arguments[i] > result) { result = arguments[i]; } } return result; } //Tests console.log(min(5,3,-2,4,14)); //-2 console.log(Math.min(5,3,-2,4,14)); //-2 console.log(max(5,3,-2,4,14)); //14 console.log(Math.max(5,3,-2,4,14)); //14 console.log(min()); //Infinity console.log(Math.min()); //Infinity console.log(max()); //-Infinity console.log(Math.max()); //-Infinity 
+2
source

Main functions:

Math.max () and Math.min () are used for numbers (or the fact that they can force numbers), you cannot directly pass an array as a parameter.

Example:

 Math.max(1,52,28) 

You may have multiple comma separated numbers.

Arrays:

This example shows how to apply them to arrays:

JavaScript: minimum and maximum values โ€‹โ€‹of an array?

The following actions are mainly performed:

 Math.max.apply(null, [1,5,2,3]); 

Why does it work?

This works because apply is a function that has all the functions that applies the function with array arguments.

Math.max.apply (null, [1,5,2,3]) is the same as Math.max (1,5,2,3)

+1
source

Well, here is min without Math.min (the code is in ES6).

 function min() { return Array.from(arguments).reduce( (minSoFar, next) => minSoFar < next ? minSoFar : next , Infinity) } 

The same logic can be implemented with a simple loop. You just need to track one of the variables through your iteration, which is the lowest value you've seen so far. The initial value of minSoFar will be Infinity . The reason is that any number other than Infinity is smaller than Infinity , but if there are no arguments, we want to return Infinity itself, because the fact that Math.min() without arguments is evaluated.

 function min() { let minSoFar = Infinity for(let i = 0, l = arguments.length; i < l; i++) { const next = arguments[i] minSoFar = minSoFar < next ? minSoFar : next } return minSoFar } 

Max can be implemented with almost the same logic, only you keep track of the highest value you've seen so far, and the initial value is -Infinity .

+1
source

This is easy to implement using Array.prototype.reduce :

 function min() { var args = Array.prototype.slice.call(arguments); var minValue = args.reduce(function(currentMin, nextNum) { if (nextNum < currentMin) { // nextNum is less than currentMin, so we return num // which will replace currentMin with nextNum return nextNum; } else { return currentMin; } }, Infinity); return minValue; } 
0
source

Source: https://habr.com/ru/post/1236535/


All Articles