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)変換
|