Integer 類型是 32 位的, 有 4 個字節, 現在我們需要能夠提取出其 32 位中的某一位.
但 Delphi 最小的整數類型也是一個字節(8位)的: Byte(無符號)、Shortint(有符號).
要不先從提取一個字節開始:
var
i: Integer;
b: Byte;
begin
i := MaxInt; {Integer 的最大值}
ShowMessage(IntToStr(i)); {2147483647}
{現在 i 的二進制表示是: 01111111 11111111 11111111 11111111}
{Interger 的最高位 0 表示這是個正數(1表示負數)}
{假如:}
i := 2146439167;
{現在 i 的二進制表示是: 01111111 11110000 00001111 11111111}
{現在其十六進制表示是: $7 F F 0 0 F F F }
{落實一下, 從右到左四個字節分別是: $FF、$0F、$F0、$7F }
{如果需要單獨提取四個字節中的某個字節, Delphi 位我們提供了兩個函數:}
b := Lo(i); {提取低位字節}
ShowMessage(Format('%.2x',[b])); {FF; 這是從右數第一個字節}
b := Hi(i); {提取高位字節}
ShowMessage(Format('%.2x',[b])); {0F; 這是從右數第二個字節}
{那麼我們怎麼提取第三個和第四個字節呢? 方法一:}
{右移 16 位, 然後再用 Lo 和 Hi 提取}
{01111111 11110000 00001111 11111111 右移 16 位後會變成:}
{ 01111111 11110000; 試一下:}
b := Lo(i shr 16);
ShowMessage(Format('%.2x',[b])); {F0; 這是從右數第三個字節}
b := Hi(i shr 16);
ShowMessage(Format('%.2x',[b])); {7F; 這是從右數第四個字節}
{當然 i 的第四個字節也可以這樣提取:}
b := Lo(i shr 24);
ShowMessage(Format('%.2x',[b])); {7F; 這是從右數第四個字節}
{現在換個思路, 假如沒有 Lo 和 Hi 函數, 我們能做到嗎? 當然能:}
b := (i and $FF);
ShowMessage(Format('%.2x',[b])); {FF; 這是從右數第一個字節}
b := (i shr 8 and $FF);
ShowMessage(Format('%.2x',[b])); {0F; 這是從右數第二個字節}
b := (i shr 16 and $FF);
ShowMessage(Format('%.2x',[b])); {F0; 這是從右數第三個字節}
b := (i shr 24 and $FF);
ShowMessage(Format('%.2x',[b])); {7F; 這是從右數第四個字節}
{這是為什麼? 換個語句塊仔細分析}
end;
//關於上面例子的補充:
var
b: Byte;
begin
{我們知道 Byte 的最大值是 255, 也就是十六進制的 $FF, 二進制的 11111111}
{這個 $FF 有這麼個特殊用途:}
b := 0 and $FF;
ShowMessage(IntToStr(b)); {0}
b := 1 and $FF;
ShowMessage(IntToStr(b)); {1}
b := 100 and $FF;
ShowMessage(IntToStr(b)); {100}
b := 255 and $FF;
ShowMessage(IntToStr(b)); {255}
{0..255 直接的任何數與 $FF 進行 and 運算後, 值不變(這從二進制的角度不難理解)}
{另外, Byte 就一個字節, 當你給它更多時, 它也只要一個字節(低位字節), 譬如:}
b := Byte(MaxInt);
ShowMessage(IntToStr(b)); {255}
{現在上面的例子應該可以理解了}
end;
回到主題:
//本例中我們把最低位叫第 0 位; 把 Integer 的最高位叫第 31 位.
var
i: Integer;
b: Byte;
begin
{還是用第一個例子中的值吧:}
i := 2146439167;
{現在 i 的二進制表示是: 01111111 11110000 00001111 11111111}
{一個字節的最大值是 $FF; 一個二進制位的最大值當然是 1, 寫成十六進制還是 $1 }
{提取第 0 位:}
b := i and 1; ShowMessage(IntToStr(b)); {1}
{提取第 0 位也可以寫作(右移0位就是沒動):}
b := i shr 0 and 1; ShowMessage(IntToStr(b)); {1}
{提取第 1 位:}
b := i shr 1 and 1; ShowMessage(IntToStr(b)); {1}
{提取第 13 位:}
b := i shr 13 and 1; ShowMessage(IntToStr(b)); {0}
{提取最高位(第 31 位):}
b := i shr 31 and 1; ShowMessage(IntToStr(b)); {0}
end;
//假如只判斷最高位, 是 0 還是 1(也就是判斷正負), 還可以這樣:
var
i: Integer;
begin
i := MaxInt; {這肯定是個正數}
if i shr 31 = 0 then ShowMessage('正'); {正}
i := -1;
if i shr 31 = 1 then ShowMessage('負'); {負}
end;