程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 為鉤子的下一步學習補課:如何提取32位中的某一位

為鉤子的下一步學習補課:如何提取32位中的某一位

編輯:Delphi

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;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved