免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: titansword2000
打印 上一主题 下一主题

[C] 位操作高手请进。已解决,感谢兄弟们的帮助! [复制链接]

论坛徽章:
0
21 [报告]
发表于 2008-05-06 10:23 |只看该作者
算是非常复杂的小程序了,需要细致的编程,不过没完全把握阁下对输出格式的定义(比如高低序),希望下面的程序能有帮助~

#include<assert.h>

#define MIN_V(x,y) ((x)<(y)?(x):(y))
void catbit(unsigned char *data,int *array,int n_array,int n_bits)
{
&nbsp;&nbsp;&nbsp;&nbsp;assert(sizeof(unsigned char) == 1);
&nbsp;&nbsp;&nbsp;&nbsp;assert(data[n_bits * n_array / 8 + 1 ]=1); //确认输入buffer可写

&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;int off_bit = 0;
&nbsp;&nbsp;&nbsp;&nbsp;int i,j;
&nbsp;&nbsp;&nbsp;&nbsp;for (i=j=0; i<n_array; ++i) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert(n_bits * i / 8 >= j); //没有少写

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert(n_bits * i == j * 8 + off_bit); //没有多写

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int off_d = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int d = array[i];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(off_d < n_bits){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int bc = MIN_V(8 - off_bit, n_bits - off_d);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data[j] |= (d & ((1<<bc)-1)) << off_bit;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d >>= bc; //具体的data输出其实只与上面这两句有关,可以自行定制


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off_d += bc;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off_bit += bc;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (off_bit == 8) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off_bit = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++j;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert(n_bits * i + off_d == j * 8 + off_bit); //分步更新中没有多写

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert(off_d == n_bits); //每次只写n_bits

&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;assert(off_bit + j * 8 == n_bits * n_array); //每次只写n_bits

&nbsp;&nbsp;&nbsp;&nbsp;
}

int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;int arr[100];
&nbsp;&nbsp;&nbsp;&nbsp;unsigned char dat[100]; //long enough

&nbsp;&nbsp;&nbsp;&nbsp;catbit(dat, arr, 100, 11);
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}

论坛徽章:
0
22 [报告]
发表于 2008-05-06 11:19 |只看该作者
https://sirch.svn.sourceforge.ne ... trunk/test/catbit.c

still not in a general way


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define TEST_N_ARRAY 3
  5. #define TEST_N_BITS 11

  6. static long long
  7. test_array[TEST_N_ARRAY] =
  8. {
  9.   0x0000011100011010,
  10.   0x0000010110100011,
  11.   0x0000011011000111
  12. };
  13. static unsigned char *test_data = NULL;

  14. static void catbit(long long *array, unsigned int n_array, unsigned int n_bits);

  15. static void
  16. catbit(long long *array, unsigned int n_array, unsigned int n_bits)
  17. {
  18.   int i;
  19.   unsigned int data_head;
  20.   unsigned int data_body;
  21.   unsigned int data_tail;
  22.   char tmp[n_bits];
  23.   
  24.   for (i = 0; i < n_array; i++)
  25.   {
  26.     data_head = (array[i] >> 0x20) & 0xffff;
  27.     data_body = (array[i] >> 0x10) & 0xffff;  
  28.     data_tail = array[i] & 0xffff;   
  29.     sprintf(tmp, "%03X%04X%04X", data_head, data_body, data_tail);
  30.     //printf("DEBUG at %d: %s\n", __LINE__, tmp);
  31.     strcat(test_data, tmp);
  32.   }
  33. }

  34. int
  35. main()
  36. {
  37.   if (test_data = (unsigned char *) malloc(TEST_N_BITS * TEST_N_ARRAY))
  38.   {
  39.     catbit(test_array, TEST_N_ARRAY, TEST_N_BITS);
  40.   }
  41.   else
  42.   {
  43.     printf("out of memory\n");

  44.     return -1;
  45.   }
  46.   printf("%s\n", test_data);
  47.   if (test_data)
  48.   {
  49.     free(test_data);
  50.     test_data = NULL;
  51.   }

  52.   return 0;
  53. }
复制代码

论坛徽章:
0
23 [报告]
发表于 2008-05-06 11:43 |只看该作者

是这样吧

void catbit(char *data, int *array, int n_array, int n_bits)
{
    int i, j, tmp, t = 0;
    int bits_int = sizeof(int) << 3;
    int mask = (1 << n_bits) - 1;
    for ( i = 0; i < n_array; i++ )
    {
        tmp = array & mask;
        for ( j = 0; j < n_bits; j++ )
            data[t++] = ((tmp << (bits_int - n_bits - 1 + j + 1)) < 0 ? '1' : '0');
    }
}

论坛徽章:
0
24 [报告]
发表于 2008-05-06 14:22 |只看该作者
原帖由 titansword2000 于 2008-5-4 15:56 发表
poor-man兄弟:
你写的这个函数是肯定不行的,主要的错误在下面这句:p1=(char *)&tmp;把整形的地址强制转换成字符形后,相当于p1指在整形的最高位,后面的n_bits个位你根本没有弄出来。


这个是没有问题的,一个int数的地址,也可以看成char的地址,当把这个单元的数看成int并改变后再存回来,那么char地址得到的当然是变化后的值,比如下面的程序:
char aa[32];
int * pi;
memset(aa,0x00,32);
pi = (int *)aa;
printf("%d",*pi);   
aa[3] = 1;
printf("%d",*pi);
程序中打印出来的两个值是不一样,这个有点像C++的引用。

关于这个程序,其实就是一个位串合并的程序,逻辑简单, 但是细节比较麻烦。前面的我回复已经修改,应该是正确的了,你可以试试。
再。前面要你写的存储顺序的函数我也写好了,放在下面:
void swap(uint64_t *p1, uint64_t *p2)
{
unsigned char *cp1, *cp2;
int i;
char test[] = {0x01,0x02,0x03,0x04};
if(*(int *)(test) == 0x01020304 )
{
  memcpy(p2,p1,sizeof(uint64_t));
  return;
}
cp1 = (char *)p1;
cp2 = (char *)p2;
cp2 += 7;
for(i=0; i<8;i++)
{
  *cp2 = *cp1;  
  cp1++;
  cp2--;
}
}
将这个函数放在memcpy函数前面就可以得到正确的结果。

[ 本帖最后由 poor-man 于 2008-5-6 14:23 编辑 ]

论坛徽章:
0
25 [报告]
发表于 2008-05-06 14:31 |只看该作者
To:20楼
你的函数是正确的,也很精练,非常感谢!唯一不同的是我只是需要二进制数据,并不是字符串类型。这几天我自己也一直在搞,但没写出通用的函数,当n_bits发生改变时,我写的函数不能很好地自动循环。从我写的BDS_pack()函数来看(该函数又调用了catbit()函数),数据编码中存在问题,换句话说,解码后再编码,数据有原始数据有出入。

同时真诚地感谢所有C/C++版块的兄弟和朋友给我的帮助,没有你们的提示和方案,我也许连那个不通用的catbit()函数都写不出来。本人的代码参照了poor-man在15楼的代码,在此特别表示感谢!

论坛徽章:
38
2017金鸡报晓
日期:2017-02-08 10:39:4215-16赛季CBA联赛之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:2720周年集字徽章-周	
日期:2022-01-13 15:12:33
26 [报告]
发表于 2008-05-06 15:49 |只看该作者
void setbitpos(unsigned char *data, int bitpos, int bit)
{
    int byte=(bitpos)/8;
    int offset=bitpos%8;

    if(bit)
    {
        data[byte]|= (1<<offset);
    }
    else
    {
        data[byte]&= ~(1<<offset);
    }
}

void catbit(unsigned char *data,int *array,int n_array,int n_bits)
{
    unsigned int bitpos=0;

    for(int i=0;i<n_array;i++)
    {
        for(int j=n_bits-1;j>=0;j--)
        {
            int bit= array[i] & (1 << j);

            setbitpos(data, bitpos++, bit);
        }
    }
}


难道非要偶出手? 三分钟搞定. 性能单说.

论坛徽章:
0
27 [报告]
发表于 2008-05-06 16:18 |只看该作者
原帖由 醉卧水云间 于 2008-5-6 15:49 发表
void setbitpos(unsigned char *data, int bitpos, int bit)
{
    int byte=(bitpos)/8;
    int offset=bitpos%8;

    if(bit)
    {
        data[byte]|= (1

嘻嘻,只是你先憋不住了而已:em11: :em11:

论坛徽章:
0
28 [报告]
发表于 2008-05-06 16:44 |只看该作者
To:醉卧水云间
高手就是高手,不一样,竟是神速,3分钟就给搞出来了,佩服!
兄弟,有没有兴趣帮我把贴在19楼的代码写个反函数?我大的那个函数BDS_unpack()是解码过程,现在要再写个编码函数BDS_pack()。先谢了!

论坛徽章:
38
2017金鸡报晓
日期:2017-02-08 10:39:4215-16赛季CBA联赛之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:2720周年集字徽章-周	
日期:2022-01-13 15:12:33
29 [报告]
发表于 2008-05-06 16:53 |只看该作者
原帖由 titansword2000 于 2008-5-6 16:44 发表
To:醉卧水云间
高手就是高手,不一样,竟是神速,3分钟就给搞出来了,佩服!
兄弟,有没有兴趣帮我把贴在19楼的代码写个反函数?我大的那个函数BDS_unpack()是解码过程,现在要再写个编码函数BDS_pack()。先 ...


你这个任务大约1000美刀 .

论坛徽章:
0
30 [报告]
发表于 2008-05-06 18:05 |只看该作者
我一般潜水,才165刀,远远不够啊,够的话肯定给兄弟,要不我把这些全给你,别嫌少啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP