judy_c
@judy_c (Judy Chang)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Python初学者にわかりやすい解説求む:def関数で『2進数の関数』つくってみた】

 Pythonを使って、自分で2進数の関数をつくりたい。

Pythonを使って2進数の関数を定義づけしました。
自分なりに2進数の関数を定義づけたのですが、動作しません。
初学者すぎて自分の関数の何が問題なのかもうまくわかりません。
新しい解決方法ではなく、わたしの書いた定義をもとに組み直しと解説を頂きたいです。

ちなみに、自分でトライしていることとしては、与えられた10進数の数字nを2進数にするために、nを2で割り、あまりが出たら、appendで空のリストに1をくわえ、あまりが出なかったら0をappenndでくわえていき、最終的にreverseでリストの中身をひっくりかえして、それをprintで表示するということをトライしています。

発生している問題・エラー

10進数が2進数に変換されない。
自分でつくった定義が間違っているようだが、何がまちがっているのかわからない。
エラーメッセージなしだが、出力結果もなし。

該当するソースコード

def bin_num(n):
    a = []
    while n >= 0:
        while n % 2 == 0:
            a.append(0)
        else:
            a.append(1)
            n = int(n/2)
    a.reverse()
    a = ''.join[str(a)]
    return a
bin_num(29)

自分で試したこと

Whileで定義づけしていますが、答えになっておらず、もやもやが晴れません。

0

1Answer

要件の理解

与えられた十進数を二進表記で出力する。

修正例と結果

修正例
def bin_num(n):
    """与えられた十進数を二進表記の文字列に変換"""
    a = [] # ビットの記録場所
    while n > 0: # 残りビットがなくなるまで繰り返す
        if n % 2 == 0: # 最下位ビットを文字として記録
            a.append('0')
        else:
            a.append('1')
        n = int(n / 2) # 1ビット右にシフト
    a.reverse() # 配列を逆転
    a = ''.join(a) # 文字の配列を連結した文字列を得る
    return a

print(bin_num(29))
結果
11101

解説

コードのコメントも併せてお読みください。

アルゴリズム

  • n2による剰余が、最下位ビットを表します。
  • n2で除した商の整数部は、nを1ビット右にシフトしたものと等しいです。
  • 1の立つビットがなくなるまで、繰り返し「最下位ビットを記録して、1ビット右にシフトする」ことで、1から順に上位のビットを抽出できます。
  • 記録したビットを逆から辿ると、上位から下位へのビット並びが得られます。

メインの繰り返し

  • n >= 0ですと、1のビットがなくなっても終わりません。
  • 1のビットがなくなったら終了するようにn > 0とします。

抽出したビットの判定と記録

  • 判定は、whlieでなくifを使用します。
    • whileは繰り返しです。
  • 最終的に生成するのは文字列なので、数値(0,1)でなく文字('0','1')を記録しておきます。

インデント

  • n = int(n/2)(1ビット右にシフト)が、判定(else:)にぶら下がっています。
  • これは、メインの繰り返し(while ~:)にぶら下げる必要があります。

文字列の連結

  • 数値型の配列[1, 1, 1, 0, 1]を文字列化(str(~))すると、'[1, 1, 1, 0, 1]'になります。
    • これを連結(join)しても結果は同じです。
    • そのため、あらかじめ、数値ではなく、文字列で配列に記録しています。
  • joinは、join[~]ではなく、join(~)と書きます。
    • この丸括弧は、関数の引数を表します。角括弧は配列ですね。

結果の表示

  • 結果を表示するためにprint(~)を使います。
4Like

Comments

  1. @judy_c

    Questioner

    tetr4lab.さん

    ご回答をありがとうございます。
    解説は回答投稿日の翌日に確認させていただきました。
    ご返信遅れまして、すみません。

    とてもわかりやすい解説をありがとうございました。

    基礎的な部分のおさらいを含め、曖昧な知識(繰り返し処理の種類と違いなど)を取り除くことからはじめたいと思います。

    よろしくお願いいたします。

Your answer might help someone💌