WEBVTT

1
00:00:00.000 --> 00:00:00.785
こんにちは。

2
00:00:00.785 --> 00:00:04.971
今回はジャバスクリプトのマス・シーエルゼット三十二を紹介します。

3
00:00:04.971 --> 00:00:10.727
これは、数値を三十二ビットで表したとき、先頭に並ぶゼロの個数を数える標準のメソッドです。

4
00:00:10.727 --> 00:00:16.353
たとえば二百五十五までは八ビットで収まりますが、二百五十六を含むなら九ビット必要です。

5
00:00:16.353 --> 00:00:20.147
このように、値を保存する幅を見積もりたい場面で役立ちます。

6
00:00:20.147 --> 00:00:28.127
この動画では、基本の使い方から、入力検証付きでビット長を求める完成例、そして三十二ビット変換の注意点までを順に解説します。

7
00:00:28.127 --> 00:00:30.874
まずは名前の意味から確かめていきましょう。

8
00:00:30.874 --> 00:00:36.892
この先頭のゼロを数える、という一見地味な操作が、保存形式の設計では大切な手がかりになります。

9
00:00:36.892 --> 00:00:38.207
まず動作環境です。

10
00:00:38.207 --> 00:00:47.118
マス・シーエルゼット三十二はジャバスクリプト標準の組み込みメソッドで、ブラウザーとノード・ジェイエスの両方で利用できます。

11
00:00:47.118 --> 00:00:51.939
二千十五年七月から主要ブラウザー間で広く利用できる機能とされており、現行のクローム、

12
00:00:51.939 --> 00:00:56.760
エッジ、ファイアフォックス、サファリで使えます。

13
00:00:56.760 --> 00:01:01.727
ブラウザー専用の機能ではないため、同じコードをそのまま実行できます。

14
00:01:01.727 --> 00:01:06.402
記事のサンプルはノード・ジェイエス二十二以降を対象としています。

15
00:01:06.402 --> 00:01:15.460
古い環境を対象にする場合は、タイプオブで関数かどうかを最初に確認し、対応していない環境では処理を進めない構成にしてください。

16
00:01:15.460 --> 00:01:22.472
対応確認は完成コードの冒頭にも入れておくと、環境差による失敗を早い段階で知らせることができます。

17
00:01:22.472 --> 00:01:24.588
基本の書き方を見ましょう。

18
00:01:24.588 --> 00:01:29.635
呼び出し方はマス・シーエルゼット三十二、かっこ、エックスです。

19
00:01:29.635 --> 00:01:34.356
シーエルゼットは、先頭のゼロを数える、という英語の略です。

20
00:01:34.356 --> 00:01:39.078
たとえば五の二進表現は一ゼロ一で、三十二桁にそろえると、その前に二十九個のゼロが並ぶため、

21
00:01:39.078 --> 00:01:43.799
戻り値は二十九になります。

22
00:01:43.799 --> 00:01:48.357
ゼロは三十二ビットすべてがゼロなので、三十二が返ります。

23
00:01:48.357 --> 00:01:50.799
途中に現れるゼロは数えません。

24
00:01:50.799 --> 00:01:55.520
五の一ゼロ一の中央のゼロは、結果に影響しない点が大切です。

25
00:01:55.520 --> 00:02:02.032
マスはコンストラクターではないため、インスタンスを作らず直接呼び出してください。

26
00:02:02.032 --> 00:02:09.684
なお、元の値は書き換えられず、戻り値だけが新しく返るため、同じ値を何度でも安全に調べられます。

27
00:02:09.684 --> 00:02:17.983
このメソッドの便利な使い方が、ビット長、つまり値の表現に必要なビット数を求めることです。

28
00:02:17.983 --> 00:02:23.453
三十二から戻り値を引くと、最上位の一までの長さが残ります。

29
00:02:23.453 --> 00:02:31.187
たとえば二百五十五では先頭のゼロが二十四個なので、三十二引く二十四で八ビットです。

30
00:02:31.187 --> 00:02:37.223
二百五十六ではゼロが二十三個になり、九ビット必要だと分かります。

31
00:02:37.223 --> 00:02:40.807
五なら三十二引く二十九で三ビットです。

32
00:02:40.807 --> 00:02:44.768
境界の値で確かめると理解しやすくなります。

33
00:02:44.768 --> 00:02:53.256
二百五十五と二百五十六のように、境目をまたぐと必要な幅が一段増えることを意識してください。

34
00:02:53.256 --> 00:03:01.744
言い換えると、先頭のゼロが少ないほど大きな値を表しており、幅の見積もりが直感と一致します。

35
00:03:01.744 --> 00:03:05.714
注意点として、引数の自動変換を確認します。

36
00:03:05.714 --> 00:03:13.466
渡された値は、まず数値へ変換され、次に三十二ビットの符号なし整数として扱われます。

37
00:03:13.466 --> 00:03:20.840
そのため文字列の五も数値の五として処理され、五点九の小数部分は取り除かれます。

38
00:03:20.840 --> 00:03:27.646
マイナス一は変換によってすべてのビットが一になるため、戻り値はゼロです。

39
00:03:27.646 --> 00:03:32.562
二の三十二乗は変換後にゼロになり、三十二が返ります。

40
00:03:32.562 --> 00:03:39.936
数値に変換できないシンボルやビッグイントを直接渡すと、タイプエラーになります。

41
00:03:39.936 --> 00:03:45.041
つまり、自動変換は入力検証の代わりにはならないのです。

42
00:03:45.041 --> 00:03:54.116
エヌエーエヌも変換後はゼロとして扱われ、三十二が返るため、正常なゼロと見分けがつかなくなります。

43
00:03:54.116 --> 00:03:55.887
ここからは完成例です。

44
00:03:55.887 --> 00:04:04.742
ビットレングス三十二という関数は、ゼロから四十二億九千四百九十六万七千二百九十五までの整数だけを受け付けます。

45
00:04:04.742 --> 00:04:11.022
最初にタイプオブで、値が数値型かどうかを確かめ、違えばタイプエラーを投げます。

46
00:04:11.022 --> 00:04:18.267
次にナンバー・イズ・インテジャーで整数かどうかを調べ、範囲の外ならレンジエラーを投げます。

47
00:04:18.267 --> 00:04:23.258
これにより、小数やエヌエーエヌ、無限大もまとめて拒否できます。

48
00:04:23.258 --> 00:04:29.376
検証を通過した値だけ、三十二引くシーエルゼット三十二でビット長を計算します。

49
00:04:29.376 --> 00:04:34.046
上限を設けることで、変換による値の折り返しを防ぐ設計です。

50
00:04:34.046 --> 00:04:38.071
関数名に三十二と入れておくことで、扱える範囲が三十二ビットまでだという前提が、

51
00:04:38.071 --> 00:04:42.096
読み手にも伝わります。

52
00:04:42.096 --> 00:04:44.981
変換結果を具体的な数で確かめます。

53
00:04:44.981 --> 00:04:49.223
ゼロはゼロビット、一は一ビット、五は三ビットです。

54
00:04:49.223 --> 00:04:57.028
二百五十五は八ビット、二百五十六は九ビットとなり、境界で幅が増える様子がはっきり分かります。

55
00:04:57.028 --> 00:05:05.003
上限の四十二億九千四百九十六万七千二百九十五は、三十二ビットすべてを使うため三十二ビットです。

56
00:05:05.003 --> 00:05:11.620
サンプルの並びは、文字列連結で値とビット数を一つの文字列にして表示しています。

57
00:05:11.620 --> 00:05:16.881
テンプレート文字列を使わない書き方でも、同じ結果が得られます。

58
00:05:16.881 --> 00:05:24.177
この結果はノード・ジェイエスの実機でも確認済みで、記事の期待出力と完全に一致しました。

59
00:05:24.177 --> 00:05:30.964
境界の前後を並べて比べることが、変換の正しさを確かめる一番分かりやすい方法です。

60
00:05:30.964 --> 00:05:33.871
期待出力をまとめて読みましょう。

61
00:05:33.871 --> 00:05:37.323
まず、最大コードが千の場合を考えます。

62
00:05:37.323 --> 00:05:42.956
千のビット長は十なので、保存幅は十ビット必要だと判断できます。

63
00:05:42.956 --> 00:05:45.318
次に不正な入力の確認です。

64
00:05:45.318 --> 00:05:50.950
文字列の五、マイナス一、一点五、上限を超える値を順に渡すと、文字列だけがタイプエラー、

65
00:05:50.950 --> 00:05:56.583
残りはレンジエラーとして報告されます。

66
00:05:56.583 --> 00:06:05.667
入力ごとにトライとキャッチで例外を受け止めているため、一件が失敗しても次の入力の確認を続けられます。

67
00:06:05.667 --> 00:06:13.662
出力の成功行とエラー行を分けて読むことで、検証が意図どおり働いているかを確かめられます。

68
00:06:13.662 --> 00:06:21.656
特に最大コードの行は、保存形式の幅を決める実務的な判断材料として、そのまま活用できます。

69
00:06:21.656 --> 00:06:24.689
間違えやすい点を二つ整理します。

70
00:06:24.689 --> 00:06:26.964
一つ目はゼロの扱いです。

71
00:06:26.964 --> 00:06:34.169
完成例では、ゼロのビット長をアプリケーション側の約束としてゼロとしています。

72
00:06:34.169 --> 00:06:38.719
ただし、文字としてゼロを表すなら一桁が必要です。

73
00:06:38.719 --> 00:06:43.933
常に一ビット以上の幅が必要な形式では、結果がゼロのときに一へ置き換えるなど、

74
00:06:43.933 --> 00:06:49.146
利用側の仕様を先に決めてください。

75
00:06:49.146 --> 00:06:52.180
二つ目は、一の個数との混同です。

76
00:06:52.180 --> 00:06:58.057
五の二進表現には一が二個ありますが、必要な長さは三ビットです。

77
00:06:58.057 --> 00:07:06.589
求めているのは最上位の一までを含む長さであり、符号ビットを含めた負数の幅とも別の問題です。

78
00:07:06.589 --> 00:07:16.068
用途によって正解が変わる部分だからこそ、関数の外ではなく仕様として、言葉に残しておくことが重要です。

79
00:07:16.068 --> 00:07:20.219
もう一つの落とし穴は、シフト演算での再計算です。

80
00:07:20.219 --> 00:07:24.630
求めたビット数から値の範囲を求めるとき、安易に一を左へシフトする書き方を使うと、

81
00:07:24.630 --> 00:07:29.040
思わぬ結果になります。

82
00:07:29.040 --> 00:07:33.797
たとえば幅三十二に対するシフト結果は、四十二億九千四百九十六万七千二百九十六にはならず、

83
00:07:33.797 --> 00:07:38.553
一になってしまいます。

84
00:07:38.553 --> 00:07:43.224
符号付き三十二ビット演算の規則が持ち込まれるためです。

85
00:07:43.224 --> 00:07:48.585
この用途では、二の幅乗、という通常の数値演算を使ってください。

86
00:07:48.585 --> 00:07:57.407
ビット演算は便利ですが、変換規則まで含めて理解していないと、境界の値で静かに壊れる点に注意が必要です。

87
00:07:57.407 --> 00:08:05.536
小さな値では正しく見える書き方ほど、大きな幅で初めて壊れるため、境界値での確認が欠かせません。

88
00:08:05.536 --> 00:08:07.103
活用場面とまとめです。

89
00:08:07.103 --> 00:08:15.650
主な使い道は、ゼロ以上の整数を詰めて保存する形式の幅の見積もりや、フラグ値がどのビット位置まで使われているかの確認です。

90
00:08:15.650 --> 00:08:21.349
最大値が千なら十ビット、六万五千五百三十五なら十六ビット、とすぐに判断できます。

91
00:08:21.349 --> 00:08:27.474
ただし、この計算だけでジャバスクリプトの数値のメモリー使用量が減るわけではありません。

92
00:08:27.474 --> 00:08:30.751
実際に詰める処理は保存形式側で別途実装します。

93
00:08:30.751 --> 00:08:39.298
導入時は、入力の最大値とゼロの扱いを関数の仕様に明記し、範囲が三十二ビットを超える場合は別の計算方法を検討してください。

94
00:08:39.298 --> 00:08:45.994
まずは身近な最大値で試し、三十二から引く、という発想が手に馴染むところから始めてみてください。

95
00:08:45.994 --> 00:08:47.276
お疲れさまでした。
