Integer 类型是 32 位的, 有 4 个字节, 现在我们需要能够提取出其 32 位中的某一位.
但 Delphi 最小的整数类型也是一个字节(8位)的: Byte(无符号)、Shortint(有符号).
要不先从提取一个字节开始:
但 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;