VIDEO LESSON

JavaScriptのMath.clz32():整数の表現に必要なビット数を求めるの解説動画

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

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

  1. 0:00こんにちは。
  2. 0:00今回はジャバスクリプトのマス・シーエルゼット三十二を紹介します。
  3. 0:04これは、数値を三十二ビットで表したとき、先頭に並ぶゼロの個数を数える標準のメソッドです。
  4. 0:10たとえば二百五十五までは八ビットで収まりますが、二百五十六を含むなら九ビット必要です。
  5. 0:16このように、値を保存する幅を見積もりたい場面で役立ちます。
  6. 0:20この動画では、基本の使い方から、入力検証付きでビット長を求める完成例、そして三十二ビット変換の注意点までを順に解説します。
  7. 0:28まずは名前の意味から確かめていきましょう。
  8. 0:30この先頭のゼロを数える、という一見地味な操作が、保存形式の設計では大切な手がかりになります。
  9. 0:36まず動作環境です。
  10. 0:38マス・シーエルゼット三十二はジャバスクリプト標準の組み込みメソッドで、ブラウザーとノード・ジェイエスの両方で利用できます。
  11. 0:47二千十五年七月から主要ブラウザー間で広く利用できる機能とされており、現行のクローム、
  12. 0:51エッジ、ファイアフォックス、サファリで使えます。
  13. 0:56ブラウザー専用の機能ではないため、同じコードをそのまま実行できます。
  14. 1:01記事のサンプルはノード・ジェイエス二十二以降を対象としています。
  15. 1:06古い環境を対象にする場合は、タイプオブで関数かどうかを最初に確認し、対応していない環境では処理を進めない構成にしてください。
  16. 1:15対応確認は完成コードの冒頭にも入れておくと、環境差による失敗を早い段階で知らせることができます。
  17. 1:22基本の書き方を見ましょう。
  18. 1:24呼び出し方はマス・シーエルゼット三十二、かっこ、エックスです。
  19. 1:29シーエルゼットは、先頭のゼロを数える、という英語の略です。
  20. 1:34たとえば五の二進表現は一ゼロ一で、三十二桁にそろえると、その前に二十九個のゼロが並ぶため、
  21. 1:39戻り値は二十九になります。
  22. 1:43ゼロは三十二ビットすべてがゼロなので、三十二が返ります。
  23. 1:48途中に現れるゼロは数えません。
  24. 1:50五の一ゼロ一の中央のゼロは、結果に影響しない点が大切です。
  25. 1:55マスはコンストラクターではないため、インスタンスを作らず直接呼び出してください。
  26. 2:02なお、元の値は書き換えられず、戻り値だけが新しく返るため、同じ値を何度でも安全に調べられます。
  27. 2:09このメソッドの便利な使い方が、ビット長、つまり値の表現に必要なビット数を求めることです。
  28. 2:17三十二から戻り値を引くと、最上位の一までの長さが残ります。
  29. 2:23たとえば二百五十五では先頭のゼロが二十四個なので、三十二引く二十四で八ビットです。
  30. 2:31二百五十六ではゼロが二十三個になり、九ビット必要だと分かります。
  31. 2:37五なら三十二引く二十九で三ビットです。
  32. 2:40境界の値で確かめると理解しやすくなります。
  33. 2:44二百五十五と二百五十六のように、境目をまたぐと必要な幅が一段増えることを意識してください。
  34. 2:53言い換えると、先頭のゼロが少ないほど大きな値を表しており、幅の見積もりが直感と一致します。
  35. 3:01注意点として、引数の自動変換を確認します。
  36. 3:05渡された値は、まず数値へ変換され、次に三十二ビットの符号なし整数として扱われます。
  37. 3:13そのため文字列の五も数値の五として処理され、五点九の小数部分は取り除かれます。
  38. 3:20マイナス一は変換によってすべてのビットが一になるため、戻り値はゼロです。
  39. 3:27二の三十二乗は変換後にゼロになり、三十二が返ります。
  40. 3:32数値に変換できないシンボルやビッグイントを直接渡すと、タイプエラーになります。
  41. 3:39つまり、自動変換は入力検証の代わりにはならないのです。
  42. 3:45エヌエーエヌも変換後はゼロとして扱われ、三十二が返るため、正常なゼロと見分けがつかなくなります。
  43. 3:54ここからは完成例です。
  44. 3:55ビットレングス三十二という関数は、ゼロから四十二億九千四百九十六万七千二百九十五までの整数だけを受け付けます。
  45. 4:04最初にタイプオブで、値が数値型かどうかを確かめ、違えばタイプエラーを投げます。
  46. 4:11次にナンバー・イズ・インテジャーで整数かどうかを調べ、範囲の外ならレンジエラーを投げます。
  47. 4:18これにより、小数やエヌエーエヌ、無限大もまとめて拒否できます。
  48. 4:23検証を通過した値だけ、三十二引くシーエルゼット三十二でビット長を計算します。
  49. 4:29上限を設けることで、変換による値の折り返しを防ぐ設計です。
  50. 4:34関数名に三十二と入れておくことで、扱える範囲が三十二ビットまでだという前提が、
  51. 4:38読み手にも伝わります。
  52. 4:42変換結果を具体的な数で確かめます。
  53. 4:44ゼロはゼロビット、一は一ビット、五は三ビットです。
  54. 4:49二百五十五は八ビット、二百五十六は九ビットとなり、境界で幅が増える様子がはっきり分かります。
  55. 4:57上限の四十二億九千四百九十六万七千二百九十五は、三十二ビットすべてを使うため三十二ビットです。
  56. 5:05サンプルの並びは、文字列連結で値とビット数を一つの文字列にして表示しています。
  57. 5:11テンプレート文字列を使わない書き方でも、同じ結果が得られます。
  58. 5:16この結果はノード・ジェイエスの実機でも確認済みで、記事の期待出力と完全に一致しました。
  59. 5:24境界の前後を並べて比べることが、変換の正しさを確かめる一番分かりやすい方法です。
  60. 5:30期待出力をまとめて読みましょう。
  61. 5:33まず、最大コードが千の場合を考えます。
  62. 5:37千のビット長は十なので、保存幅は十ビット必要だと判断できます。
  63. 5:42次に不正な入力の確認です。
  64. 5:45文字列の五、マイナス一、一点五、上限を超える値を順に渡すと、文字列だけがタイプエラー、
  65. 5:50残りはレンジエラーとして報告されます。
  66. 5:56入力ごとにトライとキャッチで例外を受け止めているため、一件が失敗しても次の入力の確認を続けられます。
  67. 6:05出力の成功行とエラー行を分けて読むことで、検証が意図どおり働いているかを確かめられます。
  68. 6:13特に最大コードの行は、保存形式の幅を決める実務的な判断材料として、そのまま活用できます。
  69. 6:21間違えやすい点を二つ整理します。
  70. 6:24一つ目はゼロの扱いです。
  71. 6:26完成例では、ゼロのビット長をアプリケーション側の約束としてゼロとしています。
  72. 6:34ただし、文字としてゼロを表すなら一桁が必要です。
  73. 6:38常に一ビット以上の幅が必要な形式では、結果がゼロのときに一へ置き換えるなど、
  74. 6:43利用側の仕様を先に決めてください。
  75. 6:49二つ目は、一の個数との混同です。
  76. 6:52五の二進表現には一が二個ありますが、必要な長さは三ビットです。
  77. 6:58求めているのは最上位の一までを含む長さであり、符号ビットを含めた負数の幅とも別の問題です。
  78. 7:06用途によって正解が変わる部分だからこそ、関数の外ではなく仕様として、言葉に残しておくことが重要です。
  79. 7:16もう一つの落とし穴は、シフト演算での再計算です。
  80. 7:20求めたビット数から値の範囲を求めるとき、安易に一を左へシフトする書き方を使うと、
  81. 7:24思わぬ結果になります。
  82. 7:29たとえば幅三十二に対するシフト結果は、四十二億九千四百九十六万七千二百九十六にはならず、
  83. 7:33一になってしまいます。
  84. 7:38符号付き三十二ビット演算の規則が持ち込まれるためです。
  85. 7:43この用途では、二の幅乗、という通常の数値演算を使ってください。
  86. 7:48ビット演算は便利ですが、変換規則まで含めて理解していないと、境界の値で静かに壊れる点に注意が必要です。
  87. 7:57小さな値では正しく見える書き方ほど、大きな幅で初めて壊れるため、境界値での確認が欠かせません。
  88. 8:05活用場面とまとめです。
  89. 8:07主な使い道は、ゼロ以上の整数を詰めて保存する形式の幅の見積もりや、フラグ値がどのビット位置まで使われているかの確認です。
  90. 8:15最大値が千なら十ビット、六万五千五百三十五なら十六ビット、とすぐに判断できます。
  91. 8:21ただし、この計算だけでジャバスクリプトの数値のメモリー使用量が減るわけではありません。
  92. 8:27実際に詰める処理は保存形式側で別途実装します。
  93. 8:30導入時は、入力の最大値とゼロの扱いを関数の仕様に明記し、範囲が三十二ビットを超える場合は別の計算方法を検討してください。
  94. 8:39まずは身近な最大値で試し、三十二から引く、という発想が手に馴染むところから始めてみてください。
  95. 8:45お疲れさまでした。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Math.clz32()で先頭のゼロビットを数え、整数の表現に必要なビット数を求める方法を解説。引数・戻り値、入力検証、ブラウザーとNode.jsの実行手順、32ビット変換の制約を学べます。

解説記事・サンプルコードを読む:JavaScriptのMath.clz32():整数の表現に必要なビット数を求める →