BBS.ChinaUnix.net
今日推荐    首页 | 新闻 | Linux | AIX | 博客 | 论坛 | 存储 | 人才 | 培训 | 知识库 | 资料 | 读书 | 手册 | 精华 | 下载 | 空间     
  会员: 密码: 免费注册 | 忘记密码 | 会员登录 | 搜索 | 帮助 


[C] 位操作高手请进。已解决,感谢兄弟们的帮助!
首页 » 论坛 » C/C++ »  
[打印] [订阅] [收藏] [推荐给朋友] [本帖文本页]
leeshuheng   帅哥
新手




UID:658125
注册:2007-12-28
最后登录: 2008-07-03
帖子:8
精华:0

可用积分:8
信誉积分:0
专家积分:0 (本版)

状态:...离线...

[个人空间] [短信] [博客]


顶部
21楼 发表于 2008-5-6 09:49 
不知道这样行不行
void catbit(unsigned char *data, int *array, int n_array, int n_bits)
{
        int j = 0, k = 0, i = 0, m = 0;
        while(i < n_array) {
                data[j] &= ~(1 << k);
                data[j] |= (array >> m & 1) << k;
                j += k / 7;
                i += m / (n_bits - 1);
                ++k;
                ++m;
                k %= 8;
                m %= n_bits;
        }
}



您对本贴的看法:鲜花[0] 臭蛋[0]
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
uppet   帅哥
骑士




UID:305391
注册:2005-8-23
最后登录: 2008-06-30
帖子:60
精华:0

可用积分:61
信誉积分:105
专家积分:0 (本版)

状态:...离线...

[个人空间] [短信] [博客]


顶部
22楼 发表于 2008-5-6 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)
{
    assert(sizeof(unsigned char) == 1);
    assert(data[n_bits * n_array / 8 + 1 ]=1); //确认输入buffer可写

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

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

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


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

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

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

    
}

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

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



您对本贴的看法:鲜花[1] 臭蛋[0]
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
涩兔子   帅哥 (sirtoozee)
精灵



UID:332502
注册:2005-11-5
最后登录: 2008-07-04
帖子:207
精华:0

可用积分:174
信誉积分:100
专家积分:4 (本版)

来自:Beijing
状态:...离线...

[个人空间] [短信] [博客]


顶部
23楼 发表于 2008-5-6 11:19 
https://sirch.svn.sourceforge.ne ... trunk/test/catbit.c

still not in a general way

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TEST_N_ARRAY 3
#define TEST_N_BITS 11

static long long
test_array[TEST_N_ARRAY] =
{
  0x0000011100011010,
  0x0000010110100011,
  0x0000011011000111
};
static unsigned char *test_data = NULL;

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

static void
catbit(long long *array, unsigned int n_array, unsigned int n_bits)
{
  int i;
  unsigned int data_head;
  unsigned int data_body;
  unsigned int data_tail;
  char tmp[n_bits];
  
  for (i = 0; i < n_array; i++)
  {
    data_head = (array[i] >> 0x20) & 0xffff;
    data_body = (array[i] >> 0x10) & 0xffff;  
    data_tail = array[i] & 0xffff;   
    sprintf(tmp, "%03X%04X%04X", data_head, data_body, data_tail);
    //printf("DEBUG at %d: %s\n", __LINE__, tmp);
    strcat(test_data, tmp);
  }
}

int
main()
{
  if (test_data = (unsigned char *) malloc(TEST_N_BITS * TEST_N_ARRAY))
  {
    catbit(test_array, TEST_N_ARRAY, TEST_N_BITS);
  }
  else
  {
    printf("out of memory\n");

    return -1;
  }
  printf("%s\n", test_data);
  if (test_data)
  {
    free(test_data);
    test_data = NULL;
  }

  return 0;
}




您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

摘除了一根儿肋骨
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
cllr
新手




UID:458307
注册:2006-8-25
最后登录: 2008-06-10
帖子:1
精华:0

可用积分:1
信誉积分:100
专家积分:0 (本版)

状态:...离线...

[个人空间] [短信] [博客]


顶部
24楼 发表于 2008-5-6 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] 臭蛋[0]
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
poor-man   帅哥
侠客




UID:298982
注册:2005-8-4
最后登录: 2008-07-03
帖子:25
精华:0

可用积分:36
信誉积分:100
专家积分:0 (本版)

状态:...离线...

[个人空间] [短信] [博客]


顶部
25楼 发表于 2008-5-6 14:22 


QUOTE:
原帖由 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 编辑 ]



您对本贴的看法:鲜花[1] 臭蛋[0]
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
titansword2000   帅哥
精灵



UID:208011
注册:2004-12-15
最后登录: 2008-06-08
帖子:248
精华:0

可用积分:183
信誉积分:100
专家积分:0 (本版)

来自:山东
状态:...离线...

[个人空间] [短信] [博客]


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

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



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

用FB真好,有BF更好;
大家好才是真的好,好的真好.
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
醉卧水云间
精灵使



UID:443805
注册:2006-7-19
最后登录: 2008-07-07
帖子:3289
精华:3

可用积分:1099
信誉积分:140
专家积分:10 (本版)

状态:...保密...

[个人空间] [短信] [博客]


顶部
27楼 发表于 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<<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] 臭蛋[0]
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
告化甲头   帅哥
骑士



UID:458768
注册:2006-8-27
最后登录: 2008-05-15
帖子:53
精华:0

可用积分:42
信誉积分:100
专家积分:0 (本版)

状态:...离线...

[个人空间] [短信] [博客]


顶部
28楼 发表于 2008-5-6 16:18 


QUOTE:
原帖由 醉卧水云间 于 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

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



您对本贴的看法:鲜花[0] 臭蛋[0]
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
titansword2000   帅哥
精灵



UID:208011
注册:2004-12-15
最后登录: 2008-06-08
帖子:248
精华:0

可用积分:183
信誉积分:100
专家积分:0 (本版)

来自:山东
状态:...离线...

[个人空间] [短信] [博客]


顶部
29楼 发表于 2008-5-6 16:44 
To:醉卧水云间
高手就是高手,不一样,竟是神速,3分钟就给搞出来了,佩服!
兄弟,有没有兴趣帮我把贴在19楼的代码写个反函数?我大的那个函数BDS_unpack()是解码过程,现在要再写个编码函数BDS_pack()。先谢了!



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

用FB真好,有BF更好;
大家好才是真的好,好的真好.
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布
醉卧水云间
精灵使



UID:443805
注册:2006-7-19
最后登录: 2008-07-07
帖子:3289
精华:3

可用积分:1099
信誉积分:140
专家积分:10 (本版)

状态:...保密...

[个人空间] [短信] [博客]


顶部
30楼 发表于 2008-5-6 16:53 


QUOTE:
原帖由 titansword2000 于 2008-5-6 16:44 发表
To:醉卧水云间
高手就是高手,不一样,竟是神速,3分钟就给搞出来了,佩服!
兄弟,有没有兴趣帮我把贴在19楼的代码写个反函数?我大的那个函数BDS_unpack()是解码过程,现在要再写个编码函数BDS_pack()。先 ...

你这个任务大约1000美刀 .



您对本贴的看法:鲜花[0] 臭蛋[0]
CU可用积分兑换Linux/Unix精品图书 |《Ubuntu标准教程》书评获奖名单公布

首页 » 论坛 » C/C++ »


 


Copyright © 2001-2008 ChinaUnix.net All Rights Reserved     联系我们:

感谢所有关心和支持过ChinaUnix的朋友们    转载本站内容请注明原作者名及出处

京ICP证041476号


清除 Cookies - ChinaUnix - Archiver - WAP - TOP

Processed in 0.087714 second(s), 4 queries , Gzip enabled