Reputation: 195
I am really curious how these functions actually work? I know there are a lot of questions about how to use these, I already know how to use them, but I couldn't find anywhere how to actually go about implementing this functionality on an array, for example, if there were no such functions? How would you code such a function if there were no helpers?
Upvotes: 15
Views: 15884
Reputation: 4080
Here is the implementation of Math.min and Math.max from a real Javascript engine
Math.max : https://github.com/v8/v8/blob/cd81dd6d740ff82a1abbc68615e8769bd467f91e/src/js/math.js#L78-L102
Math.min : https://github.com/v8/v8/blob/cd81dd6d740ff82a1abbc68615e8769bd467f91e/src/js/math.js#L105-L129
Upvotes: 0
Reputation: 23818
Here is the Math.max code in Chrome V8 engine.
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.
Upvotes: 15
Reputation: 35670
Below is how to implement the functions if Math.min()
and Math.max()
did not exist.
Functions have an arguments
object, which you can iterate through to get its values.
It's important to note that Math.min()
with no arguments returns Infinity
, and Math.max()
with no 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
Upvotes: 7
Reputation: 13869
Well, here's min
without Math.min
(code is in ES6).
function min() {
return Array.from(arguments).reduce(
(minSoFar, next) => minSoFar < next ? minSoFar : next
, Infinity)
}
The same logic could be implemented with a simple loop. You would just need to keep track of one of variable through your iteration, which is the lowest value you've seen so far. The initial value of minSoFar
would be Infinity
. The reason is that any Number except Infinity
is less than Infinity
, but in the case of no arguments sent, we want to return Infinity
itself, because that's what Math.min()
with no arguments evaluates to.
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 pretty much the same logic, only you're keeping track of the highest value you've seen so far, and the initial value is -Infinity
.
Upvotes: 2
Reputation: 4141
Basic functionality:
Math.max() and Math.min() are used on numbers (or what they can coerce into numbers) you cannot directly pass an array as a parameter.
Ex:
Math.max(1,52,28)
You can have an number of comma delimited numbers.
Arrays:
This example shows how one could apply them to arrays:
JavaScript: min & max Array values?
Basically the following works:
Math.max.apply(null, [1,5,2,3]);
Why that works?
This works because apply is a function that all functions have which applies a function with the arguments of an array.
Math.max.apply(null, [1,5,2,3]) is the same as Math.max(1,5,2,3)
Upvotes: 3
Reputation: 9388
Let's take a look at the specifications (which could/should help you in implementation!)
In ECMAScript 1st Edition (ECMA-262) (the initial definitions for both 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:
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.
The reference to 11.8.5 can be found here: The Abstract Relational Comparison Algorithm
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.
And again, 7.2.11 can be found here: Abstract Relational Comparison
Upvotes: 5
Reputation: 4842
This is easy to implement with 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;
}
Upvotes: 0