• 为钩子的下一步学习补课: 如何提取 32 位中的某一位


    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;
    
  • 相关阅读:
    POJ1094(Topological Sort)
    POJ1258(Minimum Spanning Tree,Prim)
    POJ2509(Water,Greedy)
    POJ1258(Minimum Spanning Tree,Kruskal)
    POJ1256(permutation)
    POJ2790(BFS)
    HDU 1527 取石子游戏
    POJ Mayor's posters
    HDU 1907 John
    HDU 2516 取石子游戏
  • 原文地址:https://www.cnblogs.com/del/p/1084213.html
Copyright © 2020-2023  润新知