VIDEO LESSON
JavaScriptのMath.expm1():小さな指数変化を精度よく計算するの解説動画
再生時間 8:21動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00今回はジャバスクリプトのマス・エクスピーエムワンを紹介します。
- 0:05これは、自然対数の底である約二点七一八という定数イーのエックス乗から、一を引いた値を返す標準のメソッドです。
- 0:14式だけ見れば、マス・イーエックスピーから一を引く計算と同じです。
- 0:19しかしコンピューター上では、途中の丸めによって小さな差が消えてしまうことがあります。
- 0:26エックスがゼロに近いほど、指数の結果は一に近づき、その差は失われやすくなります。
- 0:33このメソッドは、最終的に必要な一との差を直接求めることで、その精度低下を抑えます。
- 0:39なぜ直接計算では足りないのかを、この動画で順番に確かめていきます。
- 0:45まず動作環境です。
- 0:46マス・エクスピーエムワンは、二千十五年に追加されたジャバスクリプト標準の機能で、
- 0:51ブラウザーとノード・ジェイエスの両方で利用できます。
- 0:56二千十五年七月以降、主要ブラウザーを横断して使える機能とされており、現行のクローム、
- 1:01エッジ、ファイアフォックス、サファリが対象です。
- 1:06記事のサンプルはノード・ジェイエス二十二系以降を想定し、追加パッケージや通信は使いません。
- 1:12この関数は画面要素に依存しないため、同じコードを両方の環境で実行できます。
- 1:18古い組み込みブラウザーを対象にする場合は、使う前にタイプオブで関数かどうかを確認してください。
- 1:25基本の書き方を見ましょう。
- 1:27呼び出し方は、マス・エクスピーエムワン、かっこ、エックスです。
- 1:31エックスには指数として使う数値を渡します。
- 1:35戻り値はナンバー型で、イーのエックス乗から一を引いた値です。
- 1:39ゼロを渡せばゼロ、一なら約一点七一八二八、マイナス一なら約マイナスゼロ点六三二一が返ります。
- 1:46エックスが正なら結果も正、負なら結果も負の値になります。
- 1:51マスはコンストラクターではないため、新しくインスタンスを作る必要はありません。
- 1:57戻り値はプロミスではなく同期的に得られる数値なので、アウェイトやコールバックも不要です。
- 2:04入力そのものを書き換えることもありません。
- 2:07このメソッドが用意された理由を、具体例で確かめます。
- 2:11エックスに、一点一一一一からはじまる非常に小さい値を入れます。
- 2:16ゼロに近いエックスでは、正しい答えもおおむねエックス自身に近くなります。
- 2:22ところが、先に指数を計算してから一を引く方法では、結果は一点一一零二となり、
- 2:27入力から相対的に大きくずれてしまいます。
- 2:32一方、マス・エクスピーエムワンを使うと、一点一一一一という正しい値がそのまま返ります。
- 2:39ジャバスクリプトの通常の数値は有限の精度しか持たないため、一に近い数を先に作ると小さな差が丸めに埋もれるのです。
- 2:48大切なのは、差を後から引き直すのではなく、最初から差として求めることです。
- 2:54特殊な値の結果をまとめて確認します。
- 2:57エックスが無限大なら結果は無限大、マイナス無限大なら結果はマイナス一です。
- 3:03ゼロはゼロ、ナンはナンが返ります。
- 3:05大きな正の値を渡した場合も、結果が有限の範囲を超えると無限大になることがあります。
- 3:12ここで注意したいのは、範囲を外れた入力でも例外にはならず、特殊な値が静かに返ってくることです。
- 3:19計算が成功して見えても、入力が異常だった可能性は残ります。
- 3:23数値以外の入力では暗黙の変換が起きる場合もあり、意図しない値を受け入れてしまう危険があります。
- 3:31だからこそ、用途に合わせて事前の入力チェックが大切になります。
- 3:36実例として、検証つきで指数変化を計算するカルキュレートチェンジという関数を作ります。
- 3:43最初に、引数がナンバー型で、かつ有限の数値かどうかを調べます。
- 3:49文字列や無限大、ナンはここでタイプエラーとして止めます。
- 3:54次に、マス・エクスピーエムワンで計算し、結果が有限かどうかも確認します。
- 4:01大きな入力では結果が無限大になることがあるため、有限でなければレンジエラーとして報告します。
- 4:09この順番がポイントで、まず入力として扱えるかを見て、次に計算結果が扱える範囲かを見ます。
- 4:17検証と計算の役割を分けることで、読みやすい関数になります。
- 4:23計算結果を読みます。
- 4:25表示は小数六桁にそろえて、環境ごとの末尾の丸め差を読み取りやすくしています。
- 4:31ゼロなら結果はゼロです。
- 4:33一では、イーの一乗である約二点七一八から一を引いた、約一点七一八二八二になります。
- 4:41マイナス一では約マイナスゼロ点六三二一二一です。
- 4:45負の入力では、指数の結果が一より小さくなるため、差は負の値になります。
- 4:51一方、文字列の一を渡すと、数字に見えても型が違うためタイプエラーで止まります。
- 4:58マス・エクスピーエムワンを直接呼べば文字列も変換されて計算できてしまいますが、
- 5:04完成コードでは事前検査で止める設計にしています。
- 5:09これらの結果は、ノード・ジェイエスの実機でも確認済みです。
- 5:15活用例として、表示値を目標値へ滑らかに近づける計算を見ます。
- 5:20経過時間をディーティー、追従の強さをレートとすると、更新割合は一から指数を引いた形で表せます。
- 5:28これをマイナス・マス・エクスピーエムワンと書けば、経過時間が小さい場合にも一との差を直接、
- 5:32精度よく求められます。
- 5:37現在値ゼロ、目標値百、レート二、経過時間ゼロ点五秒の例では、更新割合は約ゼロ点六三二一となり、
- 5:42次の値は約六三点二一になります。
- 5:48つまり零点五秒で差の約六三パーセントを埋める計算です。
- 5:52経過時間がゼロなら更新割合もゼロで、値は動きません。
- 5:57秒とミリ秒を混ぜると追従速度が大きく変わるため、単位は統一してください。
- 6:03実行方法は二通りです。
- 6:04ブラウザーでは、空のタブを開き、開発者ツールのコンソールへ実例のコード全体を貼り付けて実行します。
- 6:12画面要素を操作しないため、専用のエイチティーエムエルは要りません。
- 6:17ノード・ジェイエスでは、コードをイーエックスピーエムワン・デモ・ジェイエスというファイルに保存し、
- 6:23ターミナルでノード、スペース、ファイル名と入力して実行します。
- 6:29最初にバージョンを確認するコマンドも併せて実行すると安心です。
- 6:33ウェブサーバーの起動や、エヌピーエム・インストールは必要ありません。
- 6:38コード全体を関数で囲んでいるので、繰り返し実行しても変数名が衝突しにくい構成になっています。
- 6:45失敗例を三つ押さえます。
- 6:47一つ目は、単に指数から一を引く式へ置き換えてしまうことです。
- 6:52イーのマイナス十六乗のような微小な入力では、直接計算の結果はゼロになってしまいますが、
- 6:57このメソッドなら差が保たれます。
- 7:01二つ目は、表示の丸めです。
- 7:03トーフィックスドは表示用の文字列を作るだけなので、後続の計算には整形前の数値を渡してください。
- 7:11丸めた値を計算へ戻すと、別の丸め誤差が加わります。
- 7:15三つ目は、入力側の精度です。
- 7:17レートと経過時間の掛け算など、関数を呼ぶ前の計算で情報が失われていれば、
- 7:22その後にこのメソッドを使っても復元できません。
- 7:26比較が必要な場面では、固定の小数と等号で比べず、許容誤差で判断してください。
- 7:32制約とまとめです。
- 7:34このメソッドを使っても、任意精度の計算になるわけではありません。
- 7:39ジャバスクリプトの数値は六十四ビットの浮動小数点数で、表せる範囲と精度には限界があります。
- 7:46大きな正の入力では結果が無限大になる可能性があり、用途ごとに、どの値を異常として扱うかを決める必要があります。
- 7:54表示値の平滑化のように、目標へ少しずつ近づける計算や、指数による増加量を求める計算では、
- 7:59小さな差を消さないことが品質に直結します。
- 8:05ゼロに近い入力で一との差が必要になったら、指数から一を引くのではなく、マス・エクスピーエムワンを選んでください。
- 8:13入力と結果の有限チェックを添えることで、安全に使えるようになります。
- 8:19お疲れさまでした。
この動画で学べること
Math.expm1()で指数関数から1を引く計算の精度低下を抑える方法を解説。引数・戻り値、ブラウザーとNode.jsの実行手順、期待出力、入力検証と値の平滑化への応用を学べます。
解説記事・サンプルコードを読む:JavaScriptのMath.expm1():小さな指数変化を精度よく計算する →