Подтвердить что ты не робот

Почему Math.min()> Math.max()?

При вводе массива в параметр минимальной и максимальной функции javascript math возвращается правильное значение:

console.log( Math.min( 5 ) ); // 5
console.log( Math.max( 2 ) ); // 2

var array = [3, 6, 1, 5, 0, -2, 3];
var minArray = Math.min( array ); // -2
var maxArray = Math.max( array ); // 6

Однако, когда я использую функцию без параметров, она возвращает неверный ответ:

console.log( Math.min() ); // Infinity
console.log( Math.max() ); // -Infinity

Это возвращает false:

console.log( Math.min() < Math.max() );


Почему это делается?

4b9b3361

Ответ 1

Конечно, это было бы потому, что стартовый номер должен быть Infinity для Math.min. Все числа, которые ниже положительной бесконечности, должны быть наименьшими из списка, если их меньше.

И для Math.max это то же самое; все числа, превышающие отрицательную бесконечность, должны быть самыми большими, если их больше нет.

Итак, для вашего первого примера:

Math.min(5), где 5 меньше положительной бесконечности (Infinity), он вернет 5.

Update

Вызов Math.min() и Math.max с параметром массива может не работать на каждой платформе. Вы должны сделать следующее:

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

Где первый параметр - аргумент области. Поскольку Math.min() и Math.max() являются "статическими" функциями, мы должны установить аргумент scope равным null.

Ответ 2

Это сложно, но важно, правильно решить, что делать агрегатные функции при передаче пустого набора.

Иногда это "интуитивно очевидно": что такое SUM без элементов? Нуль, я уверен, что все с готовностью скажут.

Иногда это меньше: что такое ПРОДУКТ без каких-либо элементов? Те, у кого есть математическая подготовка, быстро скажут "один", но это совсем не очевидно.

Тогда вы дойдете до MIN и MAX и ничего себе! Как мы получили эти бесконечности?


Один из способов решить, что должна делать совокупная функция здесь, - это то, какие действия мы хотим оставаться последовательными, даже с пустыми наборами. Например, предположим, что у нас есть эти непустые множества:

A = { 1, 2, 3 } 
B = { 4, 5 }

Теперь, это верно и действительно для любых непустых множеств, что

SUM(A union B) = SUM(SUM(A), SUM(B))
15 = 6 + 9

PRODUCT(A union B) = PRODUCT(PRODUCT(A), PRODUCT(B))
120 = 6 * 20

MIN(A union B) = MIN(MIN(A), MIN(B))
1 = MIN(1, 4)

Не было бы неплохо, скажем, математиков, если эти свойства остаются верными, даже если одно или оба набора пустые? Это, безусловно, было бы.

И он поддерживает это поведение, которое определяет, какое значение мы присваиваем SOME_AGGREGATE_FUNCTION(empty-set):

Для

SUM(A union B) = SUM(SUM(A), SUM(B))

чтобы оставаться верным, когда A пуст, а B - нет, мы должны иметь SUM(empty-set) = 0

Для

PRODUCT(A union B) = PRODUCT(PRODUCT(A), PRODUCT(B))

чтобы оставаться верным, когда A пуст, а B - нет, мы должны иметь PRODUCT(empty-set) = 1

И наконец:

Для

MIN(A union B) = MIN(MIN(A), MIN(B))

чтобы оставаться верным, когда A пуст, а B - нет, нам нужно MIN(empty-set) быть значением, которое гарантировано будет больше любого возможного значения в B, чтобы оно не мешало 'результат MIN(B). И мы получаем наш ответ: MIN(empty-set) = positive infinity

Ответ 3

Почему он это делает?

Потому что, что должен сказать стандарт,

15.8.2.11 max ([значение1 [, значение2 [,...]]])

При задании нуля или более аргументов вызовы ToNumber для каждого из аргументов и возвращает наибольшее из полученных значений.

  • Если аргументы не заданы, результатом будет -Infinity
  • Если любое значение NaN, результатом является NaN.
  • Сравнение значений для определения наибольшего значения выполняется как в 11.8.5, за исключением того, что +0 считается больше, чем 0.

15.8.2.12 мин ([значение1 [, значение2 [,...]]])

При задании нуля или более аргументов вызовы ToNumber для каждого из аргументов и возвращает наименьшее из полученных значений.

  • Если аргументы не заданы, результатом будет Infinity.
  • Если любое значение NaN, результатом является NaN.
  • Сравнение значений для определения наименьшего значения выполняется как в 11.8.5, за исключением того, что считается +0 будет больше, чем 0

p.s; Нестандартно, что Math.max() или Math.min() принимает массив. Вместо этого используйте Math.max(a,b,c,d,e,...) и т.д.

В Chrome по крайней мере;

Math.max([1,2,3,4]); // NaN

Ответ 4

По той же причине, почему сумма пустого списка обычно определяется как 0, а их произведение равно 1: это тождественный элемент операции. То есть всякий раз, когда вы включаете -Infinity в качестве элемента при вычислении max, это не влияет на результат; соответственно для бесконечности и мин.

Это разумно, потому что оно позволяет желаемые "ассоциативные" свойства для совокупных операций. Например, сумма списка такая же, как и вычисление сумм любых подписок (возможно, включая пустые) и их суммирование. Аналогично для продуктов, mins, maxes и т.д.

Ответ 5

[ECMA-262: 15.8.2.11]: max ( [ value1 [ , value2 [ , ... ] ] ] )

При задании нуля или более аргументов вызовы ToNumber для каждого из аргументов и возвращает наибольшее из полученных значений.

  • Если аргументы не заданы, результат равен -∞.
  • Если любое значение NaN, результат NaN.
  • Сравнение значений для определения наибольшего значения выполняется как в 11.8.5, за исключением того, что +0 считается больше -0.

Свойство length метода max равно 2.

[ECMA-262: 15.8.2.12]: min ( [ value1 [ , value2 [ , ... ] ] ] )

При задании нуля или более аргументов вызовы ToNumber для каждого из аргументов и возвращает наименьшее из полученных значений.

  • Если аргументы не заданы, результат равен + ∞.
  • Если любое значение NaN, результат NaN.
  • Сравнение значений для определения наименьшего значения выполняется как в 11.8.5, за исключением того, что +0 считается больше -0.

Свойство length метода min равно 2.

Без аргументов Math.min - это значение, которое вы можете использовать для вычисления итерационного минимума, а не физического минимального значения для типа. Он делает это, будучи противоположным: физическое максимальное значение для типа. (Аналогично в другом направлении для Math.max и ясно +∞ < -∞ есть false.)

то есть.

var a = [1,2,3,4,5];
var x = Math.min();
for (var i = 0; i < a.length; i++) {
    if (a[i] < x) { // will succeed on first iteration
                    // because `x` is initialised to highest possible value
       x = a[i];
    }
}

(На самом деле, может быть просто, что стандарт упрощает реализацию Math.min, поскольку он, вероятно, инициализирует свой результат до + Infinity, прежде чем выполнять свою работу над любым аргументом, используя алгоритм, подобный выше.)

Конечно, этот пример немного надуман, поскольку мы могли просто написать:

 var x = Math.min(a[0], a[1], a[2], a[3], a[4]);

Однако цикл полезен, если мы не знаем количество элементов в массиве, так как вариант Math.min, который вы используете, который принимает массив, является нестандартным.

Даже тогда вы можете сделать:

 var x = Math.min.apply(null, a);
 //               ^ reflective function-call
 //                     ^ no object instance; function is "static"
 //                           ^ array of arguments

Ответ 6

Вероятно, потому что реализация инициализирует внутреннюю сравнительную переменную до наивысшего (для Math.min) или самого низкого (для Math.max), прежде чем начать сравнивать с пустыми массивами и затем возвращает значение этой внутренней сравнительной переменной, которая конечно, не был изменен.

Ответ 7

Я не знаю точно. Но, просто сделав предположение.

Помните, как мы находим мин. Объявите переменную с чрезвычайно высоким значением (бесконечность), а затем просмотрите значения и всякий раз, когда вы найдете значение, меньшее, чем значение, сохраненное в вашей переменной, вместо этого вы сохраняете его как новый min.

Итак, поскольку вы не даете ему никаких значений для поиска min, оно дает вам начальное значение, то есть бесконечность.

То же самое для max.

Ответ 8

При отсутствии аргументов Math.min() равно бесконечности, а Math.max() - -infinity.

Вероятно, это означает, что любое значение меньше минимального, найденного до сих пор, и больше, чем максимальное.

Ответ 9

Идея состоит в том, что математически без какого-либо параметра у вас действительно есть значение undefined для минимума.

Что касается реализации мудрый, обычно значение min инициализируется очень большим значением (Infinity), которое затем обновляется по мере нахождения меньших значений. Если значение не найдено, значит, у вас Infinity в качестве минимального значения.

Дело противоположно обнаружению максимального значения, и именно поэтому у вас есть -Infinity.

Ответ 10

Теоретически результат этих функций не может быть задан. Спецификация Ecma диктует результат функций Min и Max без аргументов (см. Стр. 163).

Очевидно, вы можете иметь всевозможные аргументы о том, каков должен быть результат, но в любом случае нет строгого правильного ответа. Я думаю, Ecma выбирает это, потому что это проще всего реализовать. Обычно функция max работает примерно так:

result = -infinity;
foreach(arg in arguments)
    if(arg > result)
        result = arg;

Как вы можете видеть, возвращение -infinity, когда функция вызывается без аргументов, вообще не требует изменений.