1. 0 -> 0
  2. 1 -> 1
  3. 13 -> 3
  4. 7 -> 3
  5. 255 -> 8
  6. 1024 -> 1
  7. 65535 -> 16
コース一覧
コンピューターサイエンス入門:理論編
popcount で 1 のビット数を数える

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

popcount で 1 のビット数を数える

オンが「何個」あるかは、まだ数えられない

フラグを立てる、落とす、見る、まではできるようになりました。ところが「今いくつオンになっていますか」には、まだ答えられません。

マスクを桁の数だけ用意して全部当てる、という手もあります。しかし設定が 32 個あれば 32 行、64 個なら 64 行です。桁が増えるたびにコードが伸びる書き方は、どこかで必ず破綻します。

2 進数に含まれる 1 の個数を数える操作を popcount と呼びます。13 は 1101 なので 3、255 は 11111111 なので 8 です。

端の 1 桁だけを見て、見たら捨てる

桁の数だけコードを書かずに済ませるには、見る場所を固定します。いつもいちばん右の桁だけを見る、数え終わったらその桁を落として全体を右に詰める、これを数が無くなるまで続けます。見る場所が動かないので、書くのは 1 か所で済みます。

13 を追うと次のようになります。

プレーンテキスト

1101 右端は 1 -> 1 個目 110 右端は 0 11 右端は 1 -> 2 個目 1 右端は 1 -> 3 個目 残りが無くなったので終了

いちばん右の桁だけを取り出す道具も、全体を右へ詰める道具も、ここまでの回で出そろっています。繰り返す回数は桁数までなので、32 ビットの数でも最大 32 回です。

0 を渡したときは、繰り返しに一度も入りません。10 進数への変換では、これが空の答えになって困りました。今回は数えた個数が 0 のままで返るので、そのまま正解になります。同じ形の繰り返しでも、入り口で止まったときに正しい答えが残るかどうかは問題ごとに違う、ということです。

同じ形は、10 進数でも書ける

「端の桁を見て、見たら捨てる」という形は、2 進数だけのものではありません。10 進数で各桁の合計を出すときも、骨組みはまったく同じです。

Python

n = 4821 total = 0 while n > 0: total = total + n % 10 # 右端の桁を見る n = n // 10 # 右端を捨てて詰める print(total) # 15

見る道具と詰める道具が入れ替わるだけで、while の形も、変数の増やし方も動きません。2 進数の場合に何を当てはめるかだけ考えてください。

なお n を書き換えながら進むので、元の値は途中で消えます。あとで使うなら、始める前に別の変数へ取っておいてください。

解説

現場の話 2 つの数がどれだけ食い違っているかは、^ を取ってから 1 を数えると出ます。^ は違う桁だけ 1 にするので、その個数がそのまま食い違いの桁数です。通信の誤り検出で使うハミング距離が、これです。

要件

  1. n は 0 以上の整数と仮定して良い
  2. 文字列変換を介さず、ビット演算 (& と >> または >>>) で計算すること
  3. n = 0 のときは 0 を返すこと

入出力例

popcount(0) → 0 popcount(1) → 1 popcount(13) → 3 popcount(7) → 3 popcount(255) → 8 popcount(1024) → 1 popcount(65535) → 16

ヒント

n & 1 で最下位ビットを取り出せる (0 か 1)。これを count に加算する

n = n >> 1 (JS は n >>> 1) で次のビットを最下位に移動

while ループの条件は n > 0。n が 0 になったら終了

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • シフト演算で 2 倍 / 半分

    左シフトと右シフトで 2 のべき乗倍 / 除算を高速に行う仕組みを学び、シフト演算による倍率変換を実装する。

  • 16 進数から 10 進数への変換

    16 進数 (hexadecimal) の文字列を 10 進数の整数に変換する関数を実装し、4 ビット = 1 桁の関係を理解する。

  • 第 1 章まとめクイズ

    2 進数とビット演算の理解度を確認するまとめクイズ。

  • 文字 → ASCII コード

    1 文字を受け取り、その ASCII コード (整数) を返す関数を実装します。ord() 系の組み込みでバイト値の世界に触れます。

main.py
学習モード
エディタを読み込んでいます

メモ

popcount で 1 のビット数を数える

⌘S で保存