免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
11 [报告]
发表于 2008-05-04 12:36 |只看该作者
http://sirch.svn.sourceforge.net ... atbit.c?view=markup

头3个数字得到的有问题,而且方法还不通用

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

论坛徽章:
0
13 [报告]
发表于 2008-05-04 17:13 |只看该作者
第一层循环中设置一个中间变量
val = *(array + i) << (32 - n_bits);
第二层中就可以取得值了
val & 0x80000000 ? '1' : '0'
别忘了再左移1位。

论坛徽章:
0
14 [报告]
发表于 2008-05-05 10:51 |只看该作者

上次写的可能存在问题,现在换个思路又写了一个。

void catbit1(unsigned char *data,int *array,int n_array,int n_bits)
{
        uint64_t temp; //用64位空间来保存
        uint64_t temp1;
        int i,len;
        int start;
        uint32_t tmp;
        uint32_t mark = 0xffffffff;
        unsigned char *p;        
        start = 0;
        temp = 0;
        p = data;

        mark >>= (32 - n_bits);
        for(i=0; i< n_array; i++)
        {
                tmp = *(array+i);
                tmp &= mark;      // 将int数据的高位清空,只保存需要保存的位
                len = 64 - start; // 计算临时空间temp长度
                temp1 = tmp;      // 将32位转化为64位,32位在64的低32位
                if(len > n_bits)  // 检查临时空间长度是否能装得下位串
                {
                        temp1 <<= (len - n_bits); // 移动到合适的位置
                        temp |= temp1;            // 放到临时空间
                        start += n_bits;
                }

                else                              // 空间装不下位串
                {
                        temp1 >>= ( n_bits - len ); // 先装能装下的部分
                        temp |= temp1;
                        memcpy(p, &temp, sizeof(uint64_t)); // 保存到目标位置
                        p += sizeof(uint64_t);
                        temp1 = tmp;                        // 剩下部分下次再处理
                        temp1 <<= (64 - n_bits + len);
                        temp = temp1;
                        start = n_bits - len;
                }
        }

        memcpy(p, &temp, sizeof(uint64_t));            // 处理完了,不管有没有数据都保存一次
}
// 本程序没有处理保存顺序的关系,在我的系统(Cygwin)中,8字节在数组中的保存关系是数组的第8字节保存开始向前保存,所以这会产生问题,这是不正确的,应该掉过来,关于程序,自己写一下吧,实现起来不难。
// 昨天写的程序将关系搞反了,应该用"|"
却用成了"&",另外,还漏掉了一个重要的细节,就是最后一个copy函数没有调用。
//  我今天用取最后8位试了一下,应该是没有问题的。
//  这个在线编辑器好像有问题,对"[]"好像不能正常显示





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

论坛徽章:
0
15 [报告]
发表于 2008-05-05 15:44 |只看该作者
倒,好麻烦呀。

论坛徽章:
0
16 [报告]
发表于 2008-05-05 16:29 |只看该作者
截止到目前为止,楼上的诸多兄弟还没有一个写出正确的代码

论坛徽章:
0
17 [报告]
发表于 2008-05-06 00:19 |只看该作者
  1. void catbit(unsigned char *data,int *array,int n_array,int n_bits)
  2. {
  3.     int i,j;
  4.     unsigned char *ptr=data;
  5.     for(i=0;i<n_array;i++)
  6.         for(j=n_bits-1;j>=0;j--)
  7.             *ptr++=((array[i]&(1<<j))?1:0)+'0';
  8.     *ptr++='\0';
  9. }
复制代码

是写这么一个东西吗?

论坛徽章:
0
18 [报告]
发表于 2008-05-06 06:34 |只看该作者
感谢各位兄弟的帮忙,从上面回复的这些代码来看,我觉得很有可能是我的意思没有表达清楚,现在再表述一次。我要写的代码功能正好与下面这段BDS_unpack()代码相反,也就是原来是一个解码过程,我现在在得到文本数据后,需要把它再进行编码,也就是写一个BDS_pack()函数。


相关的宏定义:
#define PDS_DecimalScale(pds)        INT2(pds[26],pds[27])
#define BMS_bitmap(bms)                ((bms) == NULL ? NULL : (bms)+6)
#define BDS_NumBits(bds)        ((int) bds[10])
#define BDS_RefValue(bds)        (ibm2flt(bds+6))
#define BDS_BinScale(bds)        INT2(bds[4],bds[5])
#define BDS_ComplexPacking(bds)        ((bds[3] & 64) != 0)
#define BDS_Harmonic(bds)        (bds[3] & 12
#define BDS_Harmonic_RefValue(bds) (ibm2flt(bds+11))

调用:
temp = int_power(10.0, - PDS_DecimalScale(pds));
BDS_unpack(array,bds,BMS_bitmap(bms),BDS_NumBits(bds),nxny,temp*BDS_RefValue(bds),temp*int_power(2.0,BDS_BinScale(bds)));

函数本身:
/////  Beginning of "void BDS_unpack()" function  /////
static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
static unsigned int map_masks[8] = {128, 64, 32, 16, 8, 4, 2, 1};
static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};

void BDS_unpack(float *flt,unsigned char *bds,unsigned char *bitmap, int n_bits,int n,double ref,double scale)
{unsigned char *bits;

int i,mask_idx,t_bits,c_bits,j_bits;
unsigned int j, map_mask, tbits, jmask, bbits;
double jj;


if(BDS_ComplexPacking(bds))
        {fprintf(stderr,"*** Cannot decode complex packed fields n=%d***\n", n);
         exit(;
         for(i=0; i<n;i++)
                 *flt++ = UNDEFINED;
         return;
    }

if(BDS_Harmonic(bds))
        {bits = bds + 15;
     /* fill in global mean */
     *flt++ = BDS_Harmonic_RefValue(bds);
     n -= 1;
    }
else
         bits = bds + 11;  

tbits=bbits=0;

/* assume integer has 32+ bits */
if(n_bits <= 25)  /// beginning of "If1(n_bits<=25) in subfunc BDS_unpack()" ///
        {jmask = (1 << n_bits) - 1;
     t_bits = 0;
     if(bitmap)
                {for(i=0;i<n;i++)  /// beginning of "For1subfunc" ///
                        {/* check bitmap */
                         mask_idx = i & 7;
                         if(mask_idx == 0)
                                 bbits = *bitmap++;
                 if((bbits & map_masks[mask_idx]) == 0)
                                {*flt++ = UNDEFINED;
                                 continue;
                                }
                         while(t_bits < n_bits)
                                {tbits = (tbits * 256) + *bits++;
                     t_bits += 8;
                                }
                 t_bits -= n_bits;
                 j = (tbits >> t_bits) & jmask;
                 *flt++ = ref + scale*j;
                        }  /// beginning of "For1subfunc" ///
        }
         else
                {for(i=0;i<n;i++)
                        {while(t_bits < n_bits)
                                {tbits = (tbits * 256) + *bits++;
                 t_bits += 8;
                }
             t_bits -= n_bits;
             flt = (tbits >> t_bits) & jmask;
            }
             /* at least this vectorizes */
             for(i=0;i<n;i++)
                         flt = ref + scale*flt;
        }
    }  /// end of "If1(n_bits<=25) in subfunc BDS_unpack()" ///

else  /// beginning of "If1(n_bits<=25) 's else in subfunc BDS_unpack()" ///
        {/* older unoptimized code, not often used */
     c_bits = 8;
     map_mask = 128;
     while(n-- > 0)    /// beginning of "while1(n-->0) in subfunc BDS_unpack()" ///
                {if(bitmap)
                        {j = (*bitmap & map_mask);
                 if((map_mask >>= 1) == 0)
                                {map_mask = 128;
                                 bitmap++;
                                }
                 if(j == 0)
                                {*flt++ = UNDEFINED;
                                 continue;
                                }
                        }

             jj = 0.0;
             j_bits = n_bits;
             while(c_bits <= j_bits)
                        {if(c_bits ==
                                {jj = jj * 256.0  + (double) (*bits++);
                                 j_bits -= 8;
                                }
                 else
                                {jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
                                 bits++;
                                 j_bits -= c_bits;
                                 c_bits = 8;
                                }
                        }
             if(j_bits)
                        {c_bits -= j_bits;
                 jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
                        }
             *flt++ = ref + scale*jj;
                }  /// ended of "while(n-->0) in subfunc BDS_unpack()" ///
    }  /// ended of "If1(n_bits<=25) 's else in subfunc BDS_unpack(), and ended the whole If...Else..." ///

return;
}
/////  Ended of "void BDS_unpack()" function  /////

论坛徽章:
0
19 [报告]
发表于 2008-05-06 09:37 |只看该作者

回复 #1 titansword2000 的帖子


  1. #include <stdio.h>

  2. void catbit( unsigned char *data, int *array, int n_array, int n_bits )
  3. {
  4.     int i_array, i_bits, bits32;

  5.     i_array = 0;
  6.     for( ;; )
  7.     {
  8.         i_bits = n_bits;
  9.         bits32 = array[ i_array ];
  10.         while( i_bits-- )
  11.         {
  12.             *data++ = bits32 & ( 1 << i_bits ) ? '1' : '0';
  13.         }

  14.         if( ++i_array == n_array )
  15.         {
  16.             break;
  17.         }
  18.         // comment next line for release
  19.         *data++ = ',';
  20.     }

  21.     *data = '\0';
  22. }

  23. int main( int argc, char *argv[] )
  24. {
  25.     int           array[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  26.     unsigned char data[ sizeof(array) * 8 + 7 + 1 ]; // array bits + 7*, + \0

  27.     catbit( data, array, 8, 32 );
  28.     printf( "cat lower 32 bits:\n[%s]\n", data );

  29.     catbit( data, array, 8, 16 );
  30.     printf( "cat lower 16 bits:\n[%s]\n", data );

  31.     catbit( data, array, 8,  8 );
  32.     printf( "cat lower  8 bits:\n[%s]\n", data );

  33.     catbit( data, array, 8,  0 );
  34.     printf( "cat lower  0 bits:\n[%s]\n", data );

  35.     return 0;
  36. }

  37. gcc catbit.c -o catbit
  38. ./catbit
  39. cat lower 32 bits:
  40. [00000000000000000000000000000001,00000000000000000000000000000010,00000000000000000000000000000011,00000000000000000000000000000100,00000000000000000000000000000101,00000000000000000000000000000110,00000000000000000000000000000111,00000000000000000000000000001000]
  41. cat lower 16 bits:
  42. [0000000000000001,0000000000000010,0000000000000011,0000000000000100,0000000000000101,0000000000000110,0000000000000111,0000000000001000]
  43. cat lower  8 bits:
  44. [00000001,00000010,00000011,00000100,00000101,00000110,00000111,00001000]
  45. cat lower  0 bits:
  46. [,,,,,,,]
复制代码

如果你要的不是这种格式, 是不是要实现二进制数据的抽取与拼接?
将:
[00000000000000000000000000000001,
00000000000000000000000000000010,
00000000000000000000000000000011,
00000000000000000000000000000100,
00000000000000000000000000000101,
00000000000000000000000000000110,
00000000000000000000000000000111,
00000000000000000000000000001000]
抽取低8位, 变为:
[00000001,00000010,00000011,00000100,00000101,00000110,00000111,00001000]
全部是二进制数据, 而不是要字符串对吗?

[ 本帖最后由 guoruimin 于 2008-5-6 09:53 编辑 ]

论坛徽章:
0
20 [报告]
发表于 2008-05-06 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;
        }
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP