LoginSignup
34
8

More than 1 year has passed since last update.

どうしてMath.max()は-Infinityになるし[].every(条件式)はtrueになるの?

Last updated at Posted at 2022-02-04

Math.max() は与えられた複数の数値のうち最大の数を返します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/max
引数を与えないと -Infinity という最小の数値を返すのが意外というのが最近ちょっと話題になりました。

> Math.max()
<- -Infinity

配列のeveryメソッドは、配列要素のすべてで条件式が成立する場合にtrueとなります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/every
これも、空の配列で呼ぶと条件式が一回も成立していないのにtrueを返すのが意外だと話題です。

> [].every(x => false)
<- true

これらは、別に「JavaScriptの奇妙な仕様」ではありません。
集合演算のできるほぼすべての言語が同様の仕様となっています。JavaのStream.allMatch()だってC# LINQの.All()だってそう。
これらの仕様は「中立元を返している」のだと理解すると腹に落とすことができると思います。

中立元

どんな数に1をかけても同じ数です。
どんな数に0を足しても同じ数です。
これらのことを「かけ算の中立元は1だ」「足し算の中立元は0だ」と表現します。演算しても元の数と同じ結果になるような数のことを、その演算の中立元だと言うわけです。

さて、数のゼロ乗は1になることを中学で習うと思いますが、納得のいかなかった方、いらっしゃいませんか。

  • 33は3×3×3
  • 32は3×3
  • 31は3
  • 30は、3を一個もかけ合わさないってどういうこと⋯? “虚無”⋯? 仕方ない、先生が1と言ったから1だと覚えよう⋯

みたいになりそうじゃないですか。ところが1という中立元があると、以下のようにすんなり書けるわけです。(単にすんなり書けるというだけでなく、33は32の3倍、32は31の3倍、と同様に31は30の3倍が成立してキレイな関係が続くようにもなり美しくなります)

  • 33は1×3×3×3
  • 32は1×3×3
  • 31は1×3
  • 30は1

同様に0の階乗が1になることもすんなり納得できるはず。

Math.max() も同じです。「大きい方」という演算において中立元は「無限小」ですから

  • Math.max(a, b)-Infinityab のうち最大の数
  • Math.max(a)-Infinitya のうち最大の数 (→ a
  • Math.max()-Infinity のうち最大の数 (→ -Infinity

.every 、すべての論理値のANDをとるということですから、AND演算の中立元 true を使って

  • [a, b].every(cond)true && cond(a) && cond(b)
  • [a].every(cond)true && cond(a)
  • [].every(cond)true

となりますという次第です。

繰り返し演算は、対象がゼロ個だと中立元が答えになる
プログラミングでもそれ以外の分野でも役に立つことがときどきあるので是非覚えておいてください。

34
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
8