Integerを二進数文字列に変換する
99 IntToBin 動作確認 Delphi2007 更新日 2010/06/24(木)

Integerを2進数文字列
『0000 0001 1111 0101』などで表現したくなりました
また、逆に2進数文字列をIntegerに変換する必要も出てきたので
関数を作ってみました。

Integerだけだと不満になるので
Int64用のものも用意しています。

function IntToBin(x:Integer) : String;
function BinToInt(s: ShortString): Integer;

関数宣言を見ると使い方は大体わかるでしょう。
IntToBinの方は桁数固定の文字列が戻ります。

────────────────────
{-------------------------------
//  IntToBin
    Int64ToBin
機能:       Integerを二進数文字列として返します
戻り値:     必要分の固定桁数文字列
0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
備考:       IntToBinとInt64ToBinの内部処理は共通化可能だけど
            その場合Int64で処理しなければいけないので
            遅くなりそうなので完全に別にしました。
参考:       [Delphi-ML:32648] Re: 2進数への変換
履歴:       2001/06/27
//------------------------------}
function IntToBin(x:Integer) : String;
var
  i : Integer;
const
  nbyte: Integer = 4;
  {上:Integerは符号付き32bitなので4byte}
begin
  Result := StringOfChar(' ', (nbyte*10-1)); {←長さ10の文字列がnbyte個}
  for i:=nbyte*8 downto 1 do begin
    if ((x And 1) = 1) then Result[i+((i-1) shr 2)] := '1'
    else                    Result[i+((i-1) shr 2)] := '0';
    x := x shr 1;
  end;
end;

function Int64ToBin(x:Int64) : String;
var
  i : Integer;
const
  nbyte: Integer = 8;
  {上:Int64は符号付き64bitなので4byte}
begin
  Result := StringOfChar(' ', (nbyte*10-1));
  for i:=nbyte*8 downto 1 do begin
    if ((x And 1) = 1) then Result[i+((i-1) shr 2)] := '1'
    else                    Result[i+((i-1) shr 2)] := '0';
    x := x shr 1;
  end;
end;
//------------------------------


{-------------------------------
//  BinToInt
    BinToInt64
機能:       二進数文字列をIntegerとして返します
引数説明:   0,1,半角スペースで構成された2進数文字列
            文字列の長さはBinToIntは32バイトまで
            BinToInt64なら64バイトまで
            IntToBinのように綺麗に4文字スペース区切りされていなくてもよい
            例: BinToInt('10')=BinToInt('0010')=2
                BinToInt('0 10 1')=BinToInt('0101')=5
備考:       BinToIntとBinToInt64の内部処理は同一だけど
            型が違うので別の関数にしました。
参考:       [Delphi-ML:32992] Re: 2進数文字列 ->数値(BinToInt)変換
履歴:       2001/06/27
//------------------------------}
function BinToInt(s: ShortString): Integer;
var
  I, L: Integer;
  BinStr: ShortString;
const
  nbyte: Integer = 4;
  {上:Integerは符号付き32bitなので4byte}
begin
  Result := 0;
  BinStr := '';
  for I := 1 to Length(s) do
    case S[i] of
      '0', '1':
        BinStr := BinStr + s[i];
      ' ': ;
    else
      raise EConvertError.Create(s+' は二進数ではありません');
    end;

  L := Length(BinStr);
  if (L < 1) or ((8*nbyte) < L) then
      raise EConvertError.Create(s+' は二進数ではありません');

  for I := 1 to L do
    if BinStr[I] = '1' then
      Result := Result + (1 shl (L - I));
end;


function BinToInt64(s: ShortString): Int64;
var
  I, L: Integer;
  BinStr: ShortString;
const
  nbyte: Integer = 8;
  {上:Int64は符号付き64bitなので8byte}
begin
  Result := 0;
  BinStr := '';
  for I := 1 to Length(s) do
    case S[i] of
      '0', '1':
        BinStr := BinStr + s[i];
      ' ': ;
    else
      raise EConvertError.Create(s+' は二進数ではありません');
    end;

  L := Length(BinStr);
  if (L < 1) or ((8*nbyte) < L) then
    raise EConvertError.Create(s+' は二進数ではありません');

  for I := 1 to L do
    if BinStr[I] = '1' then
      Result := Result + (1 shl (L - I));
end;
//------------------------------
────────────────────

これを使って以下のようにすると

    procedure TForm1.Button1Click(Sender: TObject);
    var
      InputValue: Integer;
      i: Integer;
    begin
      InputValue := 1;

      for i:=1 to 31 do
      begin
        Memo1.Lines.Add(IntToBin(InputValue));
        InputValue := InputValue shl 1;
      end;

      for i:=1 to 31 do
      begin
        Memo1.Lines.Add(IntToBin(InputValue));
        InputValue := InputValue shr 1;
      end;
    end;

演算子
    shl(左へ1bitだけシフトする演算)や
    shr(右へ1bitだけシフトする演算)の
振る舞いがよくわかって面白いです。

また、特定bitだけを立てたり
下ろしたりすることは以下のようにすると可能です。

    procedure TForm1.Button2Click(Sender: TObject);
    var
      Value: Integer;
    begin
      {↓右から4bit目だけを1、他は0にした値}
      Value := 1 shl (4-1);
      Memo1.Lines.Add(IntToBin(Value));

      {↓左から4bit目だけを1、他は0にした値}
      Value := 1 shl (32-1-(4-1)); {←Integerは32bit}
      Memo1.Lines.Add(IntToBin(Value));

      {↓右から8bit目だけを0、他は1にした値}
      Value := 1 shl (8-1);
      Value := -1 xor Value; {←"-1"はすべて1の2進数}
      Memo1.Lines.Add(IntToBin(Value));

      {↓左から8bit目だけを0、他は1にした値}
      Value := 1 shl (32-1-(8-1));
      Value := -1 xor Value;
      Memo1.Lines.Add(IntToBin(Value));
    end;
────────────────────


参考────────────────────
[Delphi-ML:32648] Re: 2進数への変換
[Delphi-ML:32992] Re: 2進数文字列 ->数値(BinToInt)変換