JavaScriptの数学の最小関数と最大関数のパラメーターに配列を入力すると、正しい値が返されます。
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() );
なぜこれを行うのですか?
もちろん、開始番号は_Math.min
_の場合はInfinity
でなければならないためです。正の無限大よりも小さいすべての数値は、より小さいものがなければ、リストの中で最小でなければなりません。
そして、_Math.max
_の場合も同じです。負の無限大よりも大きいすべての数値は、それ以上大きくない場合に最大になります。
したがって、最初の例では:
Math.min(5)
ここで_5
_は正の無限大(Infinity
)よりも小さく、_5
_を返します。
配列パラメーターを指定してMath.min()
および_Math.max
_を呼び出すと、すべてのプラットフォームで機能しない場合があります。代わりに次のことを行う必要があります。
_Math.min.apply(null, [ 1, 2, 3, 4 , 5 ]);
_
最初のパラメータはスコープ引数です。 Math.min()
およびMath.max()
は「静的」関数であるため、スコープ引数をnullに設定する必要があります。
空のセットが渡されたときに集合関数が何を行うかを正しく決定するのは、注意が必要ですが重要です。
時々それは「直感的に明白」です:要素の合計は何ですか?ゼロ、誰もが簡単に言うと思います。
時々それはそうではありません:要素のない製品は何ですか?いくつかの数学的な訓練を受けた人はすぐに「1」と言いますが、これはまったく明白ではありません。
次に、MINとMAXに到達し、すごい!どのようにしてこれらの無限大を取得しましたか?
ここで集約関数が何をすべきかを決定する1つの方法は、空のセットであっても一貫性を保ちたい動作を検討することです。たとえば、次の空でないセットがあるとします。
_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)
_
数学者は、一方または両方のセットが空の場合でもこれらのプロパティがtrueのままであれば、それはいいことではないでしょうか。きっとそうでしょう。
また、SOME_AGGREGATE_FUNCTION(empty-set)
に割り当てる値を決定するのは、maintainintthisの動作です。
のために
_SUM(A union B) = SUM(SUM(A), SUM(B))
_
A
が空でB
が空でないときにtrueを維持するには、SUM(empty-set) = 0
が必要です
のために
_PRODUCT(A union B) = PRODUCT(PRODUCT(A), PRODUCT(B))
_
A
が空でB
が空でないときにtrueを維持するには、PRODUCT(empty-set) = 1
が必要です
そして最後に:
のために
_MIN(A union B) = MIN(MIN(A), MIN(B))
_
A
が空でB
が空でない場合にtrueを維持するには、MIN(empty-set)
がBのすべての可能な値よりも大きいことが保証されている値である必要があります。 MIN(B)
の結果を「妨害」しません。そして、私たちは答えを得ます:MIN(empty-set) = positive infinity
なぜこれを行うのですか?
それが 標準は言う が起こるべきものだからです。
15.8.2.11 max([value1 [、value2 [、…]]])
0個以上の引数を指定すると、各引数でToNumberを呼び出し、結果の値の最大値を返します。
- 引数を指定しない場合、結果は-Infinityになります
- いずれかの値がNaNの場合、結果はNaNになります。
- 最大値を決定するための値の比較は、11.8.5と同様に行われますが、+ 0は0よりも大きいと見なされます。
15.8.2.12分([value1 [、value2 [、…]]])
ゼロ個以上の引数を指定すると、各引数でToNumberを呼び出し、結果の値の最小値を返します。
- 引数が指定されていない場合、結果はInfinityです
- いずれかの値がNaNの場合、結果はNaNになります。
- 最小値を決定するための値の比較は、11.8.5と同様に行われますが、+ 0は0よりも大きいと見なされます。
pS; Math.max()
またはMath.min()
が配列を受け入れることは非標準です。代わりにMath.max(a,b,c,d,e,...)
などを使用してください。
Chrome少なくとも;
Math.max([1,2,3,4]); // NaN
空のリストの合計が通常0として定義され、その積が1として定義されるのも同じ理由です。これは、操作のID要素です。つまり、maxの計算時に-Infinityを要素として含めても、結果には影響しません。それぞれ無限大と最小。
集約操作に望ましい「連想」プロパティを許可するため、これは賢明です。たとえば、リストの合計は、任意のサブリスト(おそらく空を含む)の合計を計算し、それらを合計することと同じです。同様に、製品、最小値、最大値など。
_
[ECMA-262: 15.8.2.11]:
_max ( [ value1 [ , value2 [ , ... ] ] ] )
0個以上の引数を指定すると、各引数で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];
}
}
_
(実際、それはmay単純に標準が_Math.min
_の実装をより簡単にすることです。上記と同様のアルゴリズムを使用して、存在するすべての引数に対して作業を行います。)
もちろん、次のように書くだけなので、この例は少し工夫されています。
_ 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
_
おそらく、実装が内部比較変数を最高(Math.minの場合)または最低(Math.maxの場合)に初期化してから、空の配列との比較を開始し、この内部比較変数の値を返します。変更されていません。
よくわかりません。しかし、推測するだけです。
最小値をどのように見つけるかを覚えておいてください。非常に高い値(Infinity)の変数を宣言し、値を調べ、変数に格納されている値よりも小さい値を見つけた場合は、代わりに新しい最小値として格納します。
したがって、最小値を見つけるための値を与えていないので、初期値、つまり無限大を与えます。
最大でも同じです。
理論的には、これらの関数の結果を与えることはできません。 Ecma 指定 は、引数なしのMin関数とMax関数の結果を示します(163ページを参照)。
当然、結果はどうあるべきかについてあらゆる種類の議論を持つことができますが、とにかく厳密に正しい答えはありません。 Ecmaが実装するのが最も簡単なので、これを選択したと思います。通常、max関数はおおよそ次のように機能します
result = -infinity;
foreach(arg in arguments)
if(arg > result)
result = arg;
ご覧のとおり、引数なしで関数が呼び出されたときに-infinityを返す場合、変更はまったく必要ありません。
引数を指定しない場合、Math.min()
は無限大に等しく、Math.max()
は-infinity
。
これはおそらく、値がこれまでに見つかった最小値よりも小さく、これまでの最大値よりも大きいことを確認するためです。
考え方としては、数学的にパラメータを指定しないと、実際には最小値が未定義になります。
実装に関しては、通常、min値は非常に大きな値(Infinity)で初期化され、小さい値が見つかると更新されます。値が見つからない場合は、最小値としてInfinity
があります。
ケースは最大値を見つけることとは逆であり、そのため-Infinity
。