VIDEO LESSON

JavaScriptのMath.fround():32ビット浮動小数点に丸めて保存値と比較するの解説動画

再生時間 8:02動画を別のタブで開く ↗
動画の字幕・文字起こしを読む

再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。

  1. 0:00こんにちは。
  2. 0:00今回はジャバスクリプトのマス・エフラウンドを紹介します。
  3. 0:04これは、数値を三十二ビット単精度浮動小数点で表せる値へ丸める、標準の組み込みメソッドです。
  4. 0:11ジャバスクリプトの数値は通常、六十四ビットの倍精度で保持されます。
  5. 0:16一方、フロート・サーティツー・アレイのような三十二ビットの保存先では、表せる値の細かさが変わります。
  6. 0:23そのため、保存した値を元の入力とそのまま比べると、同じつもりでも一致しないことがあります。
  7. 0:30マス・エフラウンドで入力側も同じ精度に丸めてから比べれば、保存後の値と正しく照合できます。
  8. 0:36この動画では、その仕組みと注意点を順に解説します。
  9. 0:40まずは、保存したときに値が変わる理由から、順に確かめていきましょう。
  10. 0:45まず動作環境です。
  11. 0:46マス・エフラウンドはジャバスクリプト標準の組み込みメソッドで、ブラウザーとノード・ジェイエスの両方で利用できます。
  12. 0:55二千十五年七月から主要ブラウザー間で広く利用できる機能とされており、現行のクローム、
  13. 1:00エッジ、ファイアフォックス、サファリで使えます。
  14. 1:05ドムや外部パッケージには依存しないため、同じコードを両方の環境で実行できます。
  15. 1:11記事のサンプルはノード・ジェイエス二十二以降を対象としています。
  16. 1:15古い組み込みブラウザーで使う場合は、タイプオブで関数かどうかを事前に確認してください。
  17. 1:22対応しているかどうかを最初に確かめておくと、環境による違いで悩む時間を減らせます。
  18. 1:28基本の書き方を見ましょう。
  19. 1:30呼び出し方はマス・エフラウンド、かっこ、バリューです。
  20. 1:35引数に数値を一つ渡すと、三十二ビット単精度で表せる、最も近い数値が返ります。
  21. 1:42たとえば一点五はそのまま一点五ですが、ゼロ点一はゼロ点一ゼロゼロゼロゼロゼロゼロ一四九ゼロ一一六一二のように、
  22. 1:48わずかにずれた値になります。
  23. 1:54一点三三七も同様に、末尾までぴったりにはなりません。
  24. 1:58マスはコンストラクターではないため、インスタンスを作る必要はなく、直接呼び出します。
  25. 2:05戻り値の型はナンバーのままで、元の変数は変更されません。
  26. 2:10丸め方と特別な値を確認します。
  27. 2:12通常は、最も近い表現可能な値へ丸めます。
  28. 2:16ちょうど中間に位置する場合は、偶数丸めと呼ばれる規則が使われます。
  29. 2:21入力が大きすぎると、結果がインフィニティ、つまり無限大になる場合があります。
  30. 2:26エヌエーエヌはエヌエーエヌのまま返り、プラスゼロとマイナスゼロは符号を保ちます。
  31. 2:33ここで大切なのは、マス・エフラウンドを一度呼んだだけでは、その後の計算全体が三十二ビットになるわけではない、
  32. 2:37という点です。
  33. 2:42丸めが必要な位置で、その都度呼び出す関数だと理解してください。
  34. 2:47この性質を知っておくと、特殊な入力でも結果を予測しやすくなります。
  35. 2:52フロート・サーティツー・アレイとの関係を見ましょう。
  36. 2:56この配列の各要素は三十二ビットで保存されるため、六十四ビットの入力を入れると、
  37. 3:01保存の時点で三十二ビットの値へ丸められます。
  38. 3:06たとえばゼロ点一を保存して読み戻すと、ゼロ点一ゼロゼロゼロゼロゼロゼロ一四九ゼロ一一六一二になり、
  39. 3:11元のゼロ点一とはイコールになりません。
  40. 3:16ところが入力側にもマス・エフラウンドを適用すると、保存値と一致してトゥルーになります。
  41. 3:23つまりマス・エフラウンドは、保存先の精度を先に再現するための関数です。
  42. 3:29この考え方が、今回の中心になります。
  43. 3:32保存先と比べるときは、精度をそろえることが何より大切です。
  44. 3:36ここからは完成例です。
  45. 3:38トゥー・フィニット・フロート・サーティツーという関数は、値を受け取り、検証してからマス・エフラウンドで丸めて返します。
  46. 3:49最初に、型がナンバーで、かつ有限の数値かどうかを確かめ、問題があればタイプエラーを投げます。
  47. 3:57文字列は自動では変換しません。
  48. 4:00次に丸めを行い、その結果も有限かどうかを確認します。
  49. 4:04有限の入力でも、丸めた結果が無限大になる場合があるため、変換後の検査が欠かせません。
  50. 4:12問題があればレンジエラーを投げます。
  51. 4:15検証と変換を一つの関数にまとめると、呼び出し側の処理がシンプルになります。
  52. 4:21保存値との比較を、具体的な数で確かめます。
  53. 4:26入力は一六七七七二一七です。
  54. 4:28六十四ビットでは正確に保持できますが、この付近の三十二ビット浮動小数点では、
  55. 4:34表現できる整数の間隔が二になります。
  56. 4:39入力はちょうど中間に位置するため偶数丸めが働き、保存値は一六七七七二一六になります。
  57. 4:47そのため保存値と入力を直接比べるとフォルスです。
  58. 4:52一方、入力側にも同じ丸めを適用して比べるとトゥルーになります。
  59. 4:58これが記事の中心例で、ノード・ジェイエスの実機でも、記事の期待出力と完全に一致することを確認済みです。
  60. 5:08期待出力をまとめて読みましょう。
  61. 5:10入力一六七七七二一七に対して、保存値は一六七七七二一六、直接比較はフォルス、
  62. 5:14丸め後比較はトゥルーです。
  63. 5:18さらに、一六七七七二一六と一六七七七二一七という異なる入力をそれぞれ丸めると、
  64. 5:24どちらも同じ値になり、別の入力が一致、もトゥルーになります。
  65. 5:29不正な入力については、文字列を渡すとタイプエラー、大きすぎる値を渡すとレンジエラーが表示されます。
  66. 5:37出力の各行が、精度の違いと検証の役割を示しています。
  67. 5:41一行ずつ、どの処理の結果なのかを追って読んでください。
  68. 5:45数値を声に出して追うと、丸めの前後で何が変わったのかが分かりやすくなります。
  69. 5:51失敗例として、一致の意味の取り違えに注意しましょう。
  70. 5:55マス・エフラウンド同士の比較がトゥルーでも、それが示すのは三十二ビットへ丸めた値の一致だけです。
  71. 6:04元の値が完全に同じだったことは保証しません。
  72. 6:07先ほどの一六七七七二一六と一六七七七二一七のように、丸めによって区別が消えてしまうからです。
  73. 6:15識別子、件数、金額など、整数の正確さが必要なデータへ一律に適用するのは避けてください。
  74. 6:22元のデータを残す必要がある場合は、丸める前の値を別に保持しておきましょう。
  75. 6:28入力検証と精度の制約です。
  76. 6:31マス・エフラウンドに文字列などを渡すと、数値への暗黙の変換が行われます。
  77. 6:37変換できない文字列はエヌエーエヌになり、ビッグイントやシンボルはタイプエラーを起こします。
  78. 6:46数値を受け取る設計なら、呼び出す前に型を検査すると入力ミスを見つけやすくなります。
  79. 6:53また、有限の数値でも丸めた結果が無限大になる場合や、非常に小さい値がゼロへ丸められる場合があります。
  80. 7:02完成例の関数はゼロへの変化までは拒否しないため、微小な値の消失が問題になる用途では、
  81. 7:08許容範囲の検査を追加してください。
  82. 7:13活用場面とまとめです。
  83. 7:15マス・エフラウンドが実用的なのは、三十二ビットで保存する計測値や描画用データについて、
  84. 7:20保存後の値と照合したい場面です。
  85. 7:25一方、実際の測定値同士が十分近いかを調べる用途では、保存精度の一致だけでは要件を満たせません。
  86. 7:32機器の精度や業務上の許容差に応じた比較が別途必要です。
  87. 7:37導入前に、保存形式として同じ値か、と、業務上同じとみなせる値か、を整理してください。
  88. 7:44前者にはマス・エフラウンドが役立ちます。
  89. 7:47比較の目的を関数名やコメントに残しておくと、後から処理を変更するときにも判断しやすくなります。
  90. 7:55まずは小さな値で試し、保存値と比べる感覚をつかんでください。
  91. 8:00お疲れさまでした。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Math.fround()で数値を32ビット浮動小数点の精度に丸める方法を解説。引数・戻り値、Float32Arrayとの比較、ブラウザーとNode.jsの実行手順、入力検証と精度の制約を学べます。

解説記事・サンプルコードを読む:JavaScriptのMath.fround():32ビット浮動小数点に丸めて保存値と比較する →