zoukankan      html  css  js  c++  java
  • 为钩子的下一步学习补课: 如何提取 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;
    
  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/del/p/1084213.html
Copyright © 2011-2022 走看看