压缩BCD码 处理问题,求解

时间:2021-06-24 23:03:34
有一个字符串 

s[0]=0x01;
s[1]=0xf0;

s[2]=0x02;
s[3]=0xf0;

s[4]=0x03;
s[5]=0xf0;

s[6]=0x04;
s[7]=0xf0;

s[8]=0x05;
s[9]=0xf0;

每2个字节的最后4位去掉,并且后面的2字节向前移动4位,不知道描述的是否有问题,还是看下面的结果吧
结果就是

s[0]=0x01;
s[1]=0x00;

s[2]=0x2f;
s[3]=0x03;

s[4]=0xf0;
s[5]=0x4f;

s[6]=0x05;
s[7]=0xf0;

s[8]=0x00;
s[9]=0x00;


要得到这样的结果 怎么实现,求各为帮忙?

13 个解决方案

#1



for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

#2


没看懂要干什么

s[0]=0x01;
s[1]=0xf0;//每2个字节的最后4位去掉 0xf0 ->0x0f or 0xf+下一个字节的前4位?

 

#3


引用 1 楼 turingo 的回复:

for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

1楼  我对位操作总是糊涂,我应该从哪里学起?

#4


引用 3 楼 nonplus 的回复:
Quote: 引用 1 楼 turingo 的回复:


for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

1楼  我对位操作总是糊涂,我应该从哪里学起?


计算机组成原理去看看,你就了解了.

#5


按照你的描述, 结果应该是,

s[0]=0x01;
s[1]=0xf0;
 
s[2]=0x2f;
s[3]=0x03;
 
s[4]=0xf0;
s[5]=0x4f;
 
s[6]=0x05;
s[7]=0xf0;
 
s[8]=0x00;
s[9]=0x00;

才对呀!
可是你给的结果里面 s[1]=0x00; 是怎么回事?
另外, 1 楼的程序与你的描述和结果都不符.

#6


还没有解决呢?昨天我都看到一个类似的帖子,Lz发了几个阿?

每2个字节的最后4位去掉,显然不用操作了,1,3,5,7,9都是0xf0,后4位已经去了

后面的2字节向前移动4位,好像得不到下面的结果,你描述的好像不对,1楼的回答也得不到下面的结果

#7


参考http://www.cnblogs.com/911/archive/2008/05/20/1203477.html

引用 3 楼 nonplus 的回复:
Quote: 引用 1 楼 turingo 的回复:


for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

1楼  我对位操作总是糊涂,我应该从哪里学起?

#8


引用 1 楼 turingo 的回复:

for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

好像这个方法是不对,出来的结果,跟我的要求不相符。

#9


引用 5 楼 adlay 的回复:
按照你的描述, 结果应该是,

s[0]=0x01;
s[1]=0xf0;
 
s[2]=0x2f;
s[3]=0x03;
 
s[4]=0xf0;
s[5]=0x4f;
 
s[6]=0x05;
s[7]=0xf0;
 
s[8]=0x00;
s[9]=0x00;

才对呀!
可是你给的结果里面 s[1]=0x00; 是怎么回事?
另外, 1 楼的程序与你的描述和结果都不符.

你说对了,可是应该怎么弄呢?

#10


要不是你的需求描述有问题,或者自己稍微修正一下就好。

引用 8 楼 nonplus 的回复:
Quote: 引用 1 楼 turingo 的回复:


for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

好像这个方法是不对,出来的结果,跟我的要求不相符。

#11


引用 9 楼 nonplus 的回复:
Quote: 引用 5 楼 adlay 的回复:

按照你的描述, 结果应该是,

s[0]=0x01;
s[1]=0xf0;
 
s[2]=0x2f;
s[3]=0x03;
 
s[4]=0xf0;
s[5]=0x4f;
 
s[6]=0x05;
s[7]=0xf0;
 
s[8]=0x00;
s[9]=0x00;

才对呀!
可是你给的结果里面 s[1]=0x00; 是怎么回事?
另外, 1 楼的程序与你的描述和结果都不符.

你说对了,可是应该怎么弄呢?


如果 s[1] 是等于 0xf0 的, 下面的程序可以得到你想要的结果:

#include <stdio.h>

unsigned char get_half_byte(unsigned char* s, int n)
{
if(n % 2 == 1)
{
return s[n / 2] & 0x0f;
}
else
{
return s[n / 2] >> 4;
}
}

void set_half_byte(unsigned char* s, int n, unsigned char v)
{
if(n % 2 == 1)
{
s[n / 2] &= 0xf0;
s[n / 2] |= v & 0x0f;
}
else
{
s[n / 2] &= 0x0f;
s[n / 2] |= (v << 4) & 0xf0;
}
}

int main()
{
unsigned char s[10];

s[0]=0x01;
s[1]=0xf0;

s[2]=0x02;
s[3]=0xf0;

s[4]=0x03;
s[5]=0xf0;

s[6]=0x04;
s[7]=0xf0;

s[8]=0x05;
s[9]=0xf0;


int i = 0, j = 0;
for(; i < 20; ++i, ++j)
{
if((j + 1) % 4 == 0)
++j;

unsigned int v = 0;
if(j < 20)
v = get_half_byte(s, j);

set_half_byte(s, i, v);
}

for(i = 0; i < 10; ++i)
printf("s[%d] = 0x%02x\n", i, s[i]);
}



把它按半字的数组来处理, 每 4 个丢弃一个来拷贝就行了.

#12


多谢,我试试 

#13


#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
unsigned int iv,i;
unsigned char BCD[5];//定长10位BCD码
unsigned char sv[11];
void main() {
    iv=123456789;//最大10位无符号正整数
    //INT2BCD
    sprintf(sv,"%010u",iv);
    for (i=0;i<10;i+=2) {
        BCD[i/2]=(sv[i]<<4)|(sv[i+1]&0x0F);
    }
    printf("BCD=%02x%02x%02x%02x%02x\n",BCD[0],BCD[1],BCD[2],BCD[3],BCD[4]);
    //BCD2INT
    for (i=0;i<10;i+=2) {
        sv[i]='0'|(BCD[i/2]>>4);
        sv[i+1]='0'|(BCD[i/2]&0x0F);
    }
    sscanf(sv,"%010u",&iv);
    printf("iv=%010u\n",iv);
    getch();
}

#1



for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

#2


没看懂要干什么

s[0]=0x01;
s[1]=0xf0;//每2个字节的最后4位去掉 0xf0 ->0x0f or 0xf+下一个字节的前4位?

 

#3


引用 1 楼 turingo 的回复:

for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

1楼  我对位操作总是糊涂,我应该从哪里学起?

#4


引用 3 楼 nonplus 的回复:
Quote: 引用 1 楼 turingo 的回复:


for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

1楼  我对位操作总是糊涂,我应该从哪里学起?


计算机组成原理去看看,你就了解了.

#5


按照你的描述, 结果应该是,

s[0]=0x01;
s[1]=0xf0;
 
s[2]=0x2f;
s[3]=0x03;
 
s[4]=0xf0;
s[5]=0x4f;
 
s[6]=0x05;
s[7]=0xf0;
 
s[8]=0x00;
s[9]=0x00;

才对呀!
可是你给的结果里面 s[1]=0x00; 是怎么回事?
另外, 1 楼的程序与你的描述和结果都不符.

#6


还没有解决呢?昨天我都看到一个类似的帖子,Lz发了几个阿?

每2个字节的最后4位去掉,显然不用操作了,1,3,5,7,9都是0xf0,后4位已经去了

后面的2字节向前移动4位,好像得不到下面的结果,你描述的好像不对,1楼的回答也得不到下面的结果

#7


参考http://www.cnblogs.com/911/archive/2008/05/20/1203477.html

引用 3 楼 nonplus 的回复:
Quote: 引用 1 楼 turingo 的回复:


for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

1楼  我对位操作总是糊涂,我应该从哪里学起?

#8


引用 1 楼 turingo 的回复:

for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

好像这个方法是不对,出来的结果,跟我的要求不相符。

#9


引用 5 楼 adlay 的回复:
按照你的描述, 结果应该是,

s[0]=0x01;
s[1]=0xf0;
 
s[2]=0x2f;
s[3]=0x03;
 
s[4]=0xf0;
s[5]=0x4f;
 
s[6]=0x05;
s[7]=0xf0;
 
s[8]=0x00;
s[9]=0x00;

才对呀!
可是你给的结果里面 s[1]=0x00; 是怎么回事?
另外, 1 楼的程序与你的描述和结果都不符.

你说对了,可是应该怎么弄呢?

#10


要不是你的需求描述有问题,或者自己稍微修正一下就好。

引用 8 楼 nonplus 的回复:
Quote: 引用 1 楼 turingo 的回复:


for(i = 1; i < 9; i++)
{
    s[i] = (s[i] << 4) | (s[i + 1] >> 4);
}
s[9] <<= 4;

好像这个方法是不对,出来的结果,跟我的要求不相符。

#11


引用 9 楼 nonplus 的回复:
Quote: 引用 5 楼 adlay 的回复:

按照你的描述, 结果应该是,

s[0]=0x01;
s[1]=0xf0;
 
s[2]=0x2f;
s[3]=0x03;
 
s[4]=0xf0;
s[5]=0x4f;
 
s[6]=0x05;
s[7]=0xf0;
 
s[8]=0x00;
s[9]=0x00;

才对呀!
可是你给的结果里面 s[1]=0x00; 是怎么回事?
另外, 1 楼的程序与你的描述和结果都不符.

你说对了,可是应该怎么弄呢?


如果 s[1] 是等于 0xf0 的, 下面的程序可以得到你想要的结果:

#include <stdio.h>

unsigned char get_half_byte(unsigned char* s, int n)
{
if(n % 2 == 1)
{
return s[n / 2] & 0x0f;
}
else
{
return s[n / 2] >> 4;
}
}

void set_half_byte(unsigned char* s, int n, unsigned char v)
{
if(n % 2 == 1)
{
s[n / 2] &= 0xf0;
s[n / 2] |= v & 0x0f;
}
else
{
s[n / 2] &= 0x0f;
s[n / 2] |= (v << 4) & 0xf0;
}
}

int main()
{
unsigned char s[10];

s[0]=0x01;
s[1]=0xf0;

s[2]=0x02;
s[3]=0xf0;

s[4]=0x03;
s[5]=0xf0;

s[6]=0x04;
s[7]=0xf0;

s[8]=0x05;
s[9]=0xf0;


int i = 0, j = 0;
for(; i < 20; ++i, ++j)
{
if((j + 1) % 4 == 0)
++j;

unsigned int v = 0;
if(j < 20)
v = get_half_byte(s, j);

set_half_byte(s, i, v);
}

for(i = 0; i < 10; ++i)
printf("s[%d] = 0x%02x\n", i, s[i]);
}



把它按半字的数组来处理, 每 4 个丢弃一个来拷贝就行了.

#12


多谢,我试试 

#13


#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
unsigned int iv,i;
unsigned char BCD[5];//定长10位BCD码
unsigned char sv[11];
void main() {
    iv=123456789;//最大10位无符号正整数
    //INT2BCD
    sprintf(sv,"%010u",iv);
    for (i=0;i<10;i+=2) {
        BCD[i/2]=(sv[i]<<4)|(sv[i+1]&0x0F);
    }
    printf("BCD=%02x%02x%02x%02x%02x\n",BCD[0],BCD[1],BCD[2],BCD[3],BCD[4]);
    //BCD2INT
    for (i=0;i<10;i+=2) {
        sv[i]='0'|(BCD[i/2]>>4);
        sv[i+1]='0'|(BCD[i/2]&0x0F);
    }
    sscanf(sv,"%010u",&iv);
    printf("iv=%010u\n",iv);
    getch();
}