CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

能否高速转换

楼主wywry(Wyatt)2006-12-26 17:25:27 在 Delphi / VCL组件开发及应用 提问

我有一个数组:Aarry   of   Byte.  
  中间存放的都是0,1两种状态。  
  能否有一种最快的速度转换为16进制  
  举例说明如下:  
  数组现在数据如下(数据中有44个值):  
      1111   1101   0000   0101   1010   0101   0110   1010   0000   1000   0111  
  则结果为:FC09A96A087  
  问题点数:20、回复次数:50Top

1 楼zhangcheng125(老狼)回复于 2006-12-26 21:18:33 得分 0

可以用BinToHex函数Top

2 楼lihuasoft(坐井观天)回复于 2006-12-26 23:10:32 得分 5

按我对题目的理解,楼主提供的数组有   44   个元素,每个元素的值非1即0(即仅利用了一字节中的一位),对吗?  
          如果我对题目的理解是正确的,那么请楼主往下看我的代码(稍候贴出);如果我对题目理解不正确,即,楼主的数组仅有11个元素,那么楼主直接跳过我的代码,直接用Format('%x',[8位元素])函数输出即可。Top

3 楼lihuasoft(坐井观天)回复于 2006-12-26 23:18:23 得分 0

以下是我的代码:  
   
  {   方案一   }  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
        Arr1   :   array   [1..44]   of   byte;//这是源数组(每元素8位仅用1位),如需改为动态,请自己改  
        Arr2   :   array   of   byte;                 //这是存放结果的数组  
        I,   J,   X   :   integer;  
  begin  
        FillChar(Arr1,44,0);                                                       //---------------------  
        For   I   :=   Low(Arr1)   to   High(Arr1)   do                         //|     这部分是按楼主题目|  
                if     I     in   [1,2,3,4,5,6,8,14,16,17,19,22,24,//|中提供的数据对源数组|  
                                    26,27,29,31,37,42,43,44]   then         //|进行了赋初值                 |  
                        Arr1[I]   :=   1;                                                     //---------------------  
        {此时源数组44个元素值为11111101000001011010010101101010000010000111}  
   
        {   给结果数组定长。为了以后代码通用而这样处理。本例中44   div   4   ==   11   }  
        SetLength(Arr2,   Length(Arr1)   div   4);  
   
        X   :=   Low(Arr1);   //取源数组的下标下限,在本例中为1   。也是为了以后通用。  
   
        {   以下是实现赋值   }  
        for   I   :=   Low(Arr2)   to   High(Arr2)   do  
                begin  
                Arr2[I]   :=   0   ;  
                for   J   :=0   to   3   do  
                        Arr2[I]   :=   Arr2[I]   +   (Arr1[X+J]   shl   (3-J))   and   $F   ;  
                Inc(X,4);  
                end;  
   
        {   以下是在一个Memo中显示结果数组的各元素值   }  
        for   I   :=   Low(Arr2)   to   High(Arr2)   do  
                begin  
                memo1.Text   :=   memo1.Text   +   Format('%x',[Arr2[I]]);  
                end;  
        {   结果显示为:FD05A56A087       楼主的结果是错误的   }  
  end;  
   
  //代码看起来有点长,是因为其中包含了注释和“赋初值”、“显示结果”等等附加代码。  
  //其实,这个方案的核心思想很简单,就是把源数组每4个元素值放在了结果数组中1个元素里  
   
  Top

4 楼lihuasoft(坐井观天)回复于 2006-12-26 23:32:03 得分 0

{   方案二   }  
   
  用IntToStr转换,然后四个元素字符串相接,转换为一个16进制数......这种方案,没时间搞了。  
   
   
  {   声明:上面我给出的两种方案,可能都不够快,都达不到楼主的要求。望谅。   }Top

5 楼maozefa(阿发伯)回复于 2006-12-27 09:01:52 得分 0

Arr1   为楼主的数组  
   
  var  
      I:   Byte;  
      S:   string;  
  begin  
      S   :=   '';  
      for   I   :=   Low(Arr1)   to   High(Arr1)   do  
          S   :=   S   +   IntToHex(I,   2);  
  end;  
  Top

6 楼wywry(Wyatt)回复于 2006-12-27 09:02:09 得分 0

//首选衷心感谢:lihuasoft  
  //回去,我想到一个方法,如下:  
   
  proceudre   TForm1.Button1Client(Sender:TObject);  
  const  
    Arr1:Array[0..3]   of   Integer=(8,4,2,1);  
  var  
    s:String;  
    i,w_code:Integer;  
    ar:Array   of   Byte;  
  begin  
    s:='';//存放结果  
    w_code:=0;   //存放临时转换的字符  
    SetLength(Ar,1024);  
    Randomize;  
    for   i:=Low(Ar)   to   High(Ar)   do   //生成测试数据  
          Ar[i]:=Random(2);  
    for   I   :=   Low(Ar)   to   (High(Ar))   do  
        begin  
          w_code:=w_code   +   Ar[i]*Arr1[i   mod   4];  
          if   ((i+1)   mod   4)=0   then  
          begin  
            s:=s+IntToHex(w_code,1);  
            w_code:=0;  
          end;  
        end;  
      Memo1.Text:=s;  
  end;  
   
  //以上结果是正确,并且速度也比较快,不知大家还有没有更为巧妙的算法Top

7 楼wywry(Wyatt)回复于 2006-12-27 09:04:22 得分 0

To:maozefa(阿发伯)    
        S   :=   S   +   IntToHex(I,   2);   //你转换的是I  
  我想把数组中数据转换,你看看我上面的代码可能就明白我的意思Top

8 楼maozefa(阿发伯)回复于 2006-12-27 09:04:44 得分 0

上面不符合楼主数据的要求,改为:  
   
  var  
      I:   Byte;  
      S:   string;  
  begin  
      S   :=   '';  
      for   I   :=   Low(Arr1)   to   High(Arr1)   do  
          S   :=   S   +   IntToHex(I,   1);  
  end;  
  Top

9 楼maozefa(阿发伯)回复于 2006-12-27 09:07:09 得分 0

我想把数组中数据转换,你看看我上面的代码可能就明白我的意思  
  =================================================================  
  我转换的是数组中的数据啊,I只是个循环过渡变量。Top

10 楼wywry(Wyatt)回复于 2006-12-27 09:28:39 得分 0

{  
  :)我测试过,不行  
        能否帮我讲解一下,你的代码意义  
  }  
  var  
      I:   Byte;  
      S:   string;  
  begin  
      S   :=   '';  
      for   I   :=   Low(Arr1)   to   High(Arr1)   do   //从Arr1下标开始循环,假如从0开始,100结束  
          S   :=   S   +   IntToHex(I,   1);   //转换为16进制,循环累加。  
                                                            //此时转换的是I值,还是Arr1[I]的值.  
  end;Top

11 楼maozefa(阿发伯)回复于 2006-12-27 09:32:30 得分 0

我的循环依次取Arr1数组的值,转换为1字节的16进制字符串,加起来,不就是你要的结果吗?Top

12 楼maozefa(阿发伯)回复于 2006-12-27 09:33:47 得分 0

此时转换的是I值,还是Arr1[I]的值  
  ============================================================  
  相当于Arr1[I]Top

13 楼maozefa(阿发伯)回复于 2006-12-27 09:42:06 得分 0

我搞错了,哈哈,   多亏楼主提醒,应该是下面这样:  
   
  const  
      Arr1:   array[0..10]   of   byte   =   (15,   13,   0,   5,   10,   5,   6,   10,   0,   8,   7);  
  var  
      I:   Byte;  
      S:   string;  
  begin  
      S   :=   '';  
      for   I   :=   Low(Arr1)   to   High(Arr1)   do  
          S   :=   S   +   IntToHex(Arr1[I],   1);  
      ShowMessage(s);  
  end;  
  Top

14 楼wywry(Wyatt)回复于 2006-12-27 09:43:33 得分 0

呵,你的理解有误:  
  我是四个四个一组,换成一个16进制,不是每一个都转换  
  在数组中存放都是0与1  
  如:111110011000   则转换成F98  
   
  另I相当于Arr1[I]真的不是很明白?Top

15 楼maozefa(阿发伯)回复于 2006-12-27 09:46:19 得分 5

数组有44个元素?那你按lihuasoft(学习低调做人)   的方法去做。Top

16 楼lihuasoft(坐井观天)回复于 2006-12-27 09:52:28 得分 0

嗯,   楼主的意思是源数组里每个元素的值非1即0,即只用低1位.  
  所以楼主要探讨的实际上是这样一个问题   :   怎样把上述数组值转存到一个紧凑的新数组里去  
   
  即,如何得到这样一个数组:Arr2   :   array[0..10]   of   byte   =   (15,   13,   0,   5,   10,   5,   6,   10,   0,   8,   7);    
   
  如果要输出它的值,直接用  
   
  for   I   :=   Low(Arr2)   to   High(Arr2)   do  
                memo1.Text   :=   memo1.Text   +   Format('%x',[Arr2[I]]);  
  就可以了  
  Top

17 楼maozefa(阿发伯)回复于 2006-12-27 09:57:52 得分 0

to   lihuasoft(学习低调做人)    
   
  看来还是你的理解能力强!人老了,记忆不好,理解能力差,代码也写错,哈哈。  
  Top

18 楼lihuasoft(坐井观天)回复于 2006-12-27 10:05:11 得分 0

to   阿发伯:  
   
        大哥你谦虚了.     我在开始时也是没有搞懂楼主的意思.     可能楼主的源数据有特殊要求,只能那样存放,   的缘故吧.  
        新年快到了,   顺便祝大哥新年财运亨通!   (灌上一两层的水,楼主不要生气啊!)Top

19 楼wywry(Wyatt)回复于 2006-12-27 10:18:27 得分 0

呵,是的,我是用做将图片转换为字模使用的。  
  谢谢大家。  
  祝:  
    猪年好运!Top

20 楼maozefa(阿发伯)回复于 2006-12-27 10:46:57 得分 0

谢谢各位祝福!另外,从转换效率看,我觉得lihuasoft(学习低调做人)的转换方法比楼主的快,因为转换过程中没使用乘除法。Top

21 楼maozefa(阿发伯)回复于 2006-12-27 10:52:29 得分 0

但是,lihuasoft(学习低调做人)的  
  SetLength(Arr2,   Length(Arr1)   div   4);  
  不通用,如果Length(Arr1)不是4的整倍数呢?当然楼主的例子应该是4的整倍数,可改为:  
  SetLength(Arr2,   (Length(Arr1)   +   3)   div   4);  
   
  以上,只是就事论事,无事闲聊罢了,各位不要见怪!Top

22 楼lihuasoft(坐井观天)回复于 2006-12-27 11:14:39 得分 0

嗯,   的确是的.Top

23 楼lihuasoft(坐井观天)回复于 2006-12-27 11:25:00 得分 0

晕----我怎么就没想到   (8+3)   Div   4   仍然等于   8   Div   4   呢!   昨天晚上为这个就晕了好一阵子  
  ~   ~  
    OTop

24 楼maozefa(阿发伯)回复于 2006-12-27 11:30:42 得分 0

哈哈,这就是所谓的聪明一世,糊涂一时,你看我上面,非说I   =   Low(Arr1)就是Arr1[I],晕死,特别是解答问题时,考虑不周是正常的。  
  Top

25 楼jrcn(梦里寻软)回复于 2006-12-27 12:13:05 得分 0

markTop

26 楼zswang(伴水清清)(专家门诊清洁工)回复于 2006-12-27 12:19:42 得分 10

procedure   TForm1.Button1Click(Sender:   TObject);  
  const  
      Arr1:   array[0..3]   of   Integer   =   (8,   4,   2,   1);  
      cHexChars:   array[0..15]   of   Char   =   '0123456789ABCDEF';  
  var  
      s:   string;  
      I,   w_code:   Integer;  
      ar:   array   of   Byte;  
      vTickCount:   Longword;   //   计时  
  begin  
      s   :=   '';   //存放结果  
      w_code   :=   0;   //存放临时转换的字符  
      SetLength(Ar,   1024000);   //   测试数据开大一些  
   
      //   4个二进制换一个十六进制   //S[I   div   4   +   1]   :=   cHexChars[w_code];一起打开  
      SetLength(S,   Length(Ar)   div   4);  
   
      //Randomize;//先确定结果是一致的  
      for   I   :=   Low(Ar)   to   High(Ar)   do   //生成测试数据  
          Ar[I]   :=   Random(2);  
   
      vTickCount   :=   GetTickCount;  
      for   I   :=   Low(Ar)   to   High(Ar)   do  
      begin  
          w_code   :=   w_code   +   Ar[I]   *   Arr1[I   mod   4];  
          if   (I   +   1)   mod   4   =   0   then  
          begin  
  //             S   :=   S   +   IntToHex(w_code,   1);   //   172毫秒  
  //             S   :=   S   +   cHexChars[w_code];   //   125毫秒  
              S[I   div   4   +   1]   :=   cHexChars[w_code];   //   16毫秒   //   关键  
              w_code   :=   0;  
          end;  
      end;  
      Caption   :=   IntToStr(GetTickCount   -   vTickCount);   //   输出处理时间  
   
      Memo1.Text   :=   Copy(S,   1,   1024);   //   输出部分结果  
  end;  
   
  百万级数据量:从172毫秒优化到16毫秒   -_-!!!!!Top

27 楼maozefa(阿发伯)回复于 2006-12-27 12:27:34 得分 0

S[I   div   4   +   1]   :=   cHexChars[w_code];   //   16毫秒   //   关键  
   
  改为  
   
  S[I   shr   2   +   1]   :=   cHexChars[w_code];   //     能否还可缩短?Top

28 楼maozefa(阿发伯)回复于 2006-12-27 13:16:18 得分 0

理论上,乘除慢于加减,加减慢于位运算,我在zswang(伴水清清)基础上进一步优化,百万级数据仅仅缩短1毫秒!!!  
   
   
  procedure   TForm1.Button2Click(Sender:   TObject);  
  const  
  //     Arr1:   array[0..3]   of   Integer   =   (8,   4,   2,   1);  
    cHexChars:   array[0..15]   of   Char   =   '0123456789ABCDEF';  
  var  
      s:   string;  
      I,   J,   K,   w_code:   Integer;  
      ar:   array   of   Byte;  
      vTickCount:   Longword;   //   计时  
  begin  
      s   :=   '';   //存放结果  
      w_code   :=   0;   //存放临时转换的字符  
      SetLength(Ar,   1024000);   //   测试数据开大一些  
   
      //   4个二进制换一个十六进制   //S[I   div   4   +   1]   :=   cHexChars[w_code];一起打开  
      SetLength(S,   Length(Ar)   div   4);  
   
      //Randomize;//先确定结果是一致的  
      for   I   :=   Low(Ar)   to   High(Ar)   do   //生成测试数据  
          Ar[I]   :=   Random(2);  
      J   :=   1;  
      vTickCount   :=   GetTickCount;  
      for   I   :=   Low(Ar)   to   High(Ar)   do  
      begin  
  //         w_code   :=   w_code   +   Ar[I]   *   Arr1[I   and   3];  
  //         if   (I   +   1)   and   3   =   0   then  
  //         begin  
  //             S   :=   S   +   IntToHex(w_code,   1);   //   172毫秒  
  //             S   :=   S   +   cHexChars[w_code];   //   125毫秒  
  //             S[I   div   4   +   1]   :=   cHexChars[w_code];   //   16毫秒   //   关键  
  //         end;  
          K   :=   (I   -   Low(Ar))   and   3;  
          w_code   :=   w_code   or   Ar[I]   shl   (3   -   K);  
          if   K   =   3   then  
          begin  
              S[J]   :=   cHexChars[w_code];  
              w_code   :=   0;  
              Inc(J);  
          end;  
      end;  
      Caption   :=   IntToStr(GetTickCount   -   vTickCount);   //   输出处理时间  
   
      Memo1.Text   :=   Copy(S,   1,   1024);   //   输出部分结果  
  end;  
  Top

29 楼zswang(伴水清清)(专家门诊清洁工)回复于 2006-12-27 13:36:55 得分 0

楼上只能说明你的机器比我的好  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  const  
      cHexChars:   array[0..15]   of   Char   =   '0123456789ABCDEF';  
  var  
      S:   string;  
      I,   J:   Integer;  
      A:   array   of   Byte;  
      P:   PChar;  
      vTickCount:   Longword;   //   计时  
  begin  
      s   :=   '';   //存放结果  
      SetLength(A,   1024000);   //   测试数据开大一些  
      SetLength(S,   Length(A)   div   4);  
      for   I   :=   Low(A)   to   High(A)   do   //生成测试数据  
          A[I]   :=   Random(2);  
      P   :=   PChar(S);  
      vTickCount   :=   GetTickCount;  
      {$R-,O-}  
      for   I   :=   0   to   Length(S)   -   1   do   //少循环N次  
      begin  
          J   :=   I   shl   2;  
          P^   :=   cHexChars[  
              A[J   +   0]   shl   3   or  
              A[J   +   1]   shl   2   or  
              A[J   +   2]   shl   1   or  
              A[J   +   3]   shl   0  
          ];  
          Inc(P);  
      end;  
      {$R+,O+}  
      Caption   :=   IntToStr(GetTickCount   -   vTickCount);   //   输出处理时间  
   
      Memo1.Text   :=   Copy(S,   1,   1024);   //   输出部分结果  
  end;  
      SetLength(A,   1024000);   //   测试数据开大一些  
      SetLength(S,   Length(A)   div   4);  
      for   I   :=   Low(A)   to   High(A)   do   //生成测试数据  
          A[I]   :=   Random(2);  
      P   :=   PChar(S);  
      vTickCount   :=   GetTickCount;  
      {$R-}  
      for   I   :=   0   to   Length(S)   -   1   do  
      begin  
          J   :=   I   shl   2;  
          P^   :=   cHexChars[  
              A[J   +   0]   shl   3   or  
              A[J   +   1]   shl   2   or  
              A[J   +   2]   shl   1   or  
              A[J   +   3]   shl   0  
          ];  
          Inc(P);  
      end;  
      Caption   :=   IntToStr(GetTickCount   -   vTickCount);   //   输出处理时间  
   
      Memo1.Text   :=   Copy(S,   1,   1024);   //   输出部分结果  
  end;Top

30 楼hailants(hailants)回复于 2006-12-27 13:49:13 得分 0

下面这个函数测过速度了,转换100位的二进制消耗时间在400~500   ns   之间,不过肯定还不是最快的  
  S是源数组,T是目的数组,Len输入源数组转换长度,返回转换后目的数组长度.  
  注意:目的数组必须事先定义长度,并且是等于或大于转换后的长度,否则必出错  
  procedure   BinToHexEx(const   S;var   T;var   Len:Word);  
  var  
      i,j,Size:Word;  
      a,b:pchar;  
  begin  
      a:=pchar(s);  
      b:=pchar(T);  
      i:=Len;  
      Size:=i   div   8;  
      if   (i   mod   8)<>0   then   Size:=Size+1;  
      Len:=Size;  
      Fillchar(b[0],Size,$0);  
      while   i>0   do  
      begin  
          for   j:=0   to   7   do  
          begin  
              b[Size-1]:=char(byte(b[Size-1])   or   (byte(a[i-1])   shl   j));  
              i:=i-1;  
              if   i=0   then  
                  break;  
          end;  
          Size:=Size-1;  
      end;  
  end;Top

31 楼wywry(Wyatt)回复于 2006-12-27 13:49:19 得分 0

呵,牛,我在我的电梯上测试一下:数据产生量为(10240000)千万  
      zswang(伴水清清)(专家门诊清洁工):16ms  
      maozefa(阿发伯)                                   :47ms  
   
  :))Top

32 楼hailants(hailants)回复于 2006-12-27 13:50:09 得分 0

如果要最快的话,就要考虑ASM代码了....Top

33 楼maozefa(阿发伯)回复于 2006-12-27 13:55:35 得分 0

to   zswang(伴水清清)  
   
  我也在我的机器上测试过你的代码,确实是16毫秒,我修改后测试为15-16毫秒之间,但是多次测试,15的次数多些,我姑且认定差不多少了1毫秒!  
   
  至于wywry(Wyatt)   的测试结果,始料未及,哈哈。Top

34 楼maozefa(阿发伯)回复于 2006-12-27 14:00:00 得分 0

按wywry(Wyatt)的测试,zswang的百万级和千万级是一样的时间,那你的机器快的不得了啊!!!Top

35 楼wywry(Wyatt)回复于 2006-12-27 14:09:15 得分 0

配置也不高,是P42.6,内存768M  
  Top

36 楼hailants(hailants)回复于 2006-12-27 14:13:18 得分 0

汗,都用查表,是不是忽略了点什么,主的意思似乎是指转换后的数据仍然存放数组中,上面两位的怎么直接就变成字符串了....  
  Top

37 楼maozefa(阿发伯)回复于 2006-12-27 14:15:32 得分 0

to   wywry(Wyatt)  
   
  我用千万级数据重新测试2段代码,结果是:  
      zswang(伴水清清)(专家门诊清洁工):47ms   -   62ms      
      maozefa(阿发伯)                                   :46ms   -   47ms  
   
   
  Top

38 楼wq_quake(Paladin 象风一样的游侠)回复于 2006-12-27 14:21:08 得分 0

速度和空间是互相矛盾的,由逆向思维也可以知道要想换得速度就得利用空间。建立一个字符串s='0123456789abcdef';对于二进制就通过位操作求出其值对应下标的s[四位二进制值]就可以得到十六进制码。Top

39 楼wywry(Wyatt)回复于 2006-12-27 14:26:01 得分 0

我的测试也没错误,我是使用delphi2006  
  我测试N遍,基本都是那样的结果Top

40 楼hailants(hailants)回复于 2006-12-27 14:26:12 得分 0

倒,又一个没听明白的,上面的方法我也知道,我的意思是说他们转换出来的十六进制码是字符数据......  
  楼主似乎想要是数值...Top

41 楼maozefa(阿发伯)回复于 2006-12-27 14:30:29 得分 0

to   wywry(Wyatt)    
   
  你检查2段代码都是千万级?算了,争这个没意思了,主要是探讨一下。祝大家开心!Top

42 楼hailants(hailants)回复于 2006-12-27 14:35:21 得分 0

......我测zswang(伴水清清)(专家门诊清洁工):的也是15-16.....Top

43 楼wywry(Wyatt)回复于 2006-12-27 14:48:10 得分 0

呵,是的,一样没错误  
  见下面:  
    你的代码:  
  procedure   TForm2.Button4Click(Sender:   TObject);  
  const  
  //     Arr1:   array[0..3]   of   Integer   =   (8,   4,   2,   1);  
    cHexChars:   array[0..15]   of   Char   =   '0123456789ABCDEF';  
  var  
      s:   string;  
      I,   J,   K,   w_code:   Integer;  
      ar:   array   of   Byte;  
      vTickCount:   Longword;   //   计时  
  begin  
      s   :=   '';   //存放结果  
      w_code   :=   0;   //存放临时转换的字符  
      SetLength(Ar,   10240000);   //   测试数据开大一些  
   
      //   4个二进制换一个十六进制   //S[I   div   4   +   1]   :=   cHexChars[w_code];一起打开  
      SetLength(S,   Length(Ar)   div   4);  
   
      //Randomize;//先确定结果是一致的  
      for   I   :=   Low(Ar)   to   High(Ar)   do   //生成测试数据  
          Ar[I]   :=   Random(2);  
      J   :=   1;  
      vTickCount   :=   GetTickCount;  
      for   I   :=   Low(Ar)   to   High(Ar)   do  
      begin  
  //         w_code   :=   w_code   +   Ar[I]   *   Arr1[I   and   3];  
  //         if   (I   +   1)   and   3   =   0   then  
  //         begin  
  //             S   :=   S   +   IntToHex(w_code,   1);   //   172毫秒  
  //             S   :=   S   +   cHexChars[w_code];   //   125毫秒  
  //             S[I   div   4   +   1]   :=   cHexChars[w_code];   //   16毫秒   //   关键  
  //         end;  
          K   :=   (I   -   Low(Ar))   and   3;  
          w_code   :=   w_code   or   Ar[I]   shl   (3   -   K);  
          if   K   =   3   then  
          begin  
              S[J]   :=   cHexChars[w_code];  
              w_code   :=   0;  
              Inc(J);  
          end;  
      end;  
      Caption   :=   IntToStr(GetTickCount   -   vTickCount);   //   输出处理时间  
   
  //     RichEdit1.Text   :=   S;//Copy(S,   1,   1024);   //   输出部分结果  
   
   
  end;  
   
   
  zswang(伴水清清):  
  procedure   TForm2.Button2Click(Sender:   TObject);  
  const  
      cHexChars:   array[0..15]   of   Char   =   '0123456789ABCDEF';  
  var  
      S:   string;  
      I,   J:   Integer;  
      A:   array   of   Byte;  
      P:   PChar;  
      vTickCount:   Longword;   //   计时  
  begin  
      s   :=   '';   //存放结果  
      SetLength(A,   10240000);   //   测试数据开大一些  
      SetLength(S,   Length(A)   div   4);  
      for   I   :=   Low(A)   to   High(A)   do   //生成测试数据  
          A[I]   :=   Random(2);  
      P   :=   PChar(S);  
      vTickCount   :=   GetTickCount;  
      {$R-,O-}  
      for   I   :=   0   to   Length(S)   -   1   do   //少循环N次  
      begin  
          J   :=   I   shl   2;  
          P^   :=   cHexChars[  
              A[J   +   0]   shl   3   or  
              A[J   +   1]   shl   2   or  
              A[J   +   2]   shl   1   or  
              A[J   +   3]   shl   0  
          ];  
          Inc(P);  
      end;  
      {$R+,O+}  
   
      Caption   :=   IntToStr(GetTickCount   -   vTickCount);   //   输出处理时间  
   
  //     RichEdit1.Text   :=   S1;//Copy(S,   1,   1024);   //   输出部分结果  
   
  end;  
   
   
  Top

44 楼maozefa(阿发伯)回复于 2006-12-27 14:59:01 得分 0

晕,我修改和比较的是他第一次回复的代码!!!他第二次的回复代码是在我回复之后重新写的,我根本就没看。  
  Top

45 楼wywry(Wyatt)回复于 2006-12-27 15:02:51 得分 0

晕,感谢!Top

46 楼maozefa(阿发伯)回复于 2006-12-27 15:07:56 得分 0

我只是想看看用位操作比乘除快多少而已,如果楼主对速度追求很高的话,可使用ASM,当然也要是优化的ASM。Top

47 楼Radar2006(中华英雄)回复于 2006-12-27 16:34:15 得分 0

这种精神值得学习~!Top

48 楼wr960204(武稀松)回复于 2006-12-27 21:49:38 得分 0

查表法最快  
  const  
        ZZ:array[0..1,0..1,0..1,0..1]   of   char   =  
        (  
          ((  
          ('0','1'),  
          ('2','3')  
          ),  
          (  
          ('4','5'),  
          ('6','7')  
          )),  
          ((  
          ('8','9'),  
          ('A','B')  
          ),  
          (  
          ('C','D'),  
          ('E','F')  
          ))  
        );  
         
   
  function   T(Array_Address:   PByte;   Num:   Integer):   string;  
  type  
        PBytes   =   ^TBytes;  
        TBytes   =   array[0..0]   of   Byte;  
  var  
        P                                 :   PBytes;  
        I                                 :   Integer;  
  begin  
        SetLength(Result,   Num   div   4);  
        P   :=   PBytes(Array_Address);  
        for   I   :=   0   to   (Num   div   4)   -   1   do  
        begin  
              Result[I   +   1]   :=   ZZ[P^[4*I],P^[4*I+1],P^[4*I+2],P^[4*i+3]];  
        end;  
  end;  
   
   
  //调用例子  
  var  
      B:array[0..43]   of   Byte   =   (1,1,1,1,  
                                            1,1,0,1,  
                                            0,0,0,0,  
                                            0,1,0,1,  
                                            1,0,1,0,  
                                            0,1,0,1,  
                                            0,1,1,0,  
                                            1,0,1,0,  
                                            0,0,0,0,  
                                            1,0,0,0,  
                                            0,1,1,1);  
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
      I:Integer;  
  begin  
      ShowMessage(T(@B,44));  
  end;  
  Top

49 楼lijun51888(sun)回复于 2006-12-27 22:50:05 得分 0

高手很多啊Top

50 楼xuancaoer(当回复为'mark'的时候请别给我分)回复于 2006-12-28 01:51:27 得分 0

markTop

相关问题

关键词

得分解答快速导航

  • 帖主:wywry
  • lihuasoft
  • maozefa
  • zswang

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo