现在有一个byte数组array[1..20] of Byte,我想从其中某一字节的某一位取出几位,组成一个新的字节,该怎么做呢?有什么快速的办法吗?

解决方案 »

  1.   

    本帖最后由 bdmh 于 2010-09-21 10:18:19 编辑
      

  2.   

    我想从其中某一字节的某一位取出几位
    纠结啊。呵呵。
    Delphi有位操作运算符   Not、And、Or、Xor、Shl、Shr 
    还有函数BinToHex、StrToInt 
    灵活运用就可以解决位操作的问题
      

  3.   

    http://hackdiy.com/I-9998030.html
    可以的话,分都给我吧。这个够详细了。
      

  4.   

    const
      Bytes:array[1..20] of Byte=(33,2,77,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);//aByteNum表示数组中第几个字节,aBitNum表示第几位
    //返回值为取出的某一位
    function GetB(aByteNum,aBitNum:Integer):Integer;
    begin
      result:=Bytes[aByteNum]and(1 shl aBitNum);
    end;//例如取第3字节的第2位,第5字节的第3,第7字节的第4位组成一个字节
    procedure TForm1.Button1Click(Sender: TObject);
    var
      a:Byte;
    begin
      a:=0 or GetB(3,2) or GetB(5,3) or GetB(7,4);
      ShowMessage(IntToStr(a));
    end;
      

  5.   

    如果你是想按照位来操作一些东西,建议你使用TBits类而不是Byte数组
    通过TBits类的Bits属性,你可以按照位来读取或者设置数据
      

  6.   

    下面是一个TBits和Byte数组之间的转换函数
    从Byte数组到TBits的转换函数可以从数组的任意字节的任意位开始转换
    从TBits到Byte数组的转换函数可以从任意位开始转换
    //从Byte数组到Bits
    //第一个参数是Byte数组的首地址
    //第二个参数是转换的字节数 * 8 (也就是一个要转换多少位)
    //第三个参数是Bits
    //第四个参数是从当前给定的Byte数组的首地址的第几位开始转换
    procedure BytesToBits(PB: PByte; Count: Integer; Bits: TBits; Start: Integer = 1);
    var
      I, J, K: Integer;
    begin
      if (Start > 7) or (Start < 0) then
        raise Exception.Create('无效的起始位置');  Bits.Size := Count;
      K := 0;
      J := Start - 1;
      for I := 0 to Count - 1 do
      begin
        Bits[K] := Boolean(((Integer(PB^) shr J) and $01));
        Inc(K);
        Inc(J);
        if J = 8 then
          Inc(PB);
        J := J mod 8;
      end;
    end;//从Bits到Byte数组
    // 第一个参数是原始数据Bits
    // 第二个参数是输出数组的首地址
    // 第三个参数是要输出的字节的个数 * 8 (也就是按照位的个数输出)
    // 第四个参数是Bits的起始位置,默认是0表示从头开始取,用户可以指定从任意位开取
    procedure BitsToBytes(Bits: TBits; PB: PByte; Count: Integer; Start: Integer = 1);
    var
      I, J, K: Integer;
    begin
      if Bits.Size < (Count + Start - 1) then
        raise Exception.Create('没有足够的数据可供转换');  K := Start - 1;
      J := 0;
      for I := 0 to Count - 1 do
      begin
        PB^ := PB^ or (Integer(Bits[K]) shl J);
        Inc(K);    Inc(J);
        if J = 8 then
          Inc(PB);
        J := J mod 8;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      Bits: TBits;
      a, b, c, d: array[1..20] of Byte;
      I, J: Integer;
    begin
      Bits := TBits.Create;
      try
        //赋值
        Randomize;
        for i := Low(a) to High(a) do
          a[i] := Random(256);    //从Byte数组到Bits
        BytesToBits(@a[1], (High(a) - Low(a) + 1) * 8, Bits, 1);    ZeroMemory(@b[1], SizeOf(b));
        //从Bits到Byte数组,可以通过最后一个参数指定从哪位开始取
        BitsToBytes(Bits, @b[1], (High(b) - Low(b) + 1) * 8, 1);    ZeroMemory(@c[1], SizeOf(c));
        //从Bits到Byte数组,
        //从原来数组的第 4 个字节的第 5 位开始取,一共取7个字节(连续的56位)
        BitsToBytes(Bits, @c[1], 7 * 8, (4 - 1) * 8 + 5);    Bits.Size := 0;
        //从Byte数组的第三个字节的第2位开始转换,转换78位(也就是9个字节多6位) 到Bits
        BytesToBits(@a[3], 9 * 8 + 6, Bits, 2);    ZeroMemory(@d[1], SizeOf(d));
        //从Bits到Byte数组,
        //从原来数组的第 2 个字节的第 3 位开始取,一共取6个字节零5位(连续的53位)
        BitsToBytes(Bits, @d[1], 6 * 8 + 5, (2 - 1) * 8 + 3);    //输出
        Memo1.Lines.Clear;
        Memo1.Lines.Add('        a|   b|   c|   d');
        Memo1.Lines.Add('#############################');
        for I := Low(a) to High(a) do
        begin
          //输出原始数据
          Memo1.Lines.Add(Format('%-4d#%4d*%4d*%4d*%4d#%4d',
            [I, a[i], b[i], c[i], d[i], I]));      //按位输出
          for J := 0 to 7 do
          begin
            Memo1.Lines.Add(Format('%4d#%4d|%4d|%4d|%4d#%-4d',
              [J + 1, (a[i] shr J) and $01, (b[i] shr J) and $01,
              (c[i] shr J) and $01, (d[i] shr J) and $01, J + 1]));
          end;
        end;
      finally
        Bits.Free;
      end;
    end;
      

  7.   

    修正了一下,加入了参数校验,呵呵
    //从Byte数组到Bits
    //第一个参数是Byte数组的首地址
    //第二个参数是转换的字节数 * 8 (也就是一个要转换多少位)
    //第三个参数是Bits
    //第四个参数是从当前给定的Byte数组的首地址的第几位开始转换
    procedure BytesToBits(PB: PByte; Count: Cardinal; Bits: TBits; Start: Integer = 1);
    var
      I, J, K: Integer;
    begin
      if (Start > 7) or (Start < 0) then
        raise Exception.Create('无效的起始位置');  Bits.Size := Count;
      K := 0;
      J := Start - 1;
      for I := 0 to Count - 1 do
      begin
        Bits[K] := Boolean(((Integer(PB^) shr J) and $01));
        Inc(K);
        Inc(J);
        if J = 8 then
          Inc(PB);
        J := J mod 8;
      end;
    end;//从Bits到Byte数组
    // 第一个参数是原始数据Bits
    // 第二个参数是输出数组的首地址
    // 第三个参数是要输出的字节的个数 * 8 (也就是按照位的个数输出)
    // 第四个参数是Bits的起始位置,默认是1表示从头开始取,用户可以指定从任意位开取
    procedure BitsToBytes(Bits: TBits; PB: PByte; Count: Cardinal; Start: Integer = 1);
    var
      I, J, K: Integer;
    begin
      if Bits.Size < (Integer(Count) + Start - 1) then
        raise Exception.Create('没有足够的数据可供转换');
      if Start < 1 then
        raise Exception.Create('无效的起始位置');
      K := Start - 1;
      J := 0;
      for I := 0 to Count - 1 do
      begin
        PB^ := PB^ or (Integer(Bits[K]) shl J);
        Inc(K);    Inc(J);
        if J = 8 then
          Inc(PB);
        J := J mod 8;
      end;
    end;
      

  8.   

    这样的问题 发帖 效率太低
    直接网上baidu下多快!
      

  9.   

    是在做位图一类的东东么?
    TBits,简单,实惠,一片顶一大片
    ^-^
      

  10.   

    c怎么做,delphi也怎么做:xor、shl、shr
    效率不够就嵌入汇编