首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BCD中的位移位

BCD中的位移位
EN

Stack Overflow用户
提问于 2013-07-23 12:57:57
回答 3查看 1.1K关注 0票数 3

我正在将BCD数字的位向左或向右移位,以快速乘以或除以2。下面是一个快速左移的示例:

代码语言:javascript
复制
void LShift(unsigned char *arg)
{
   int i, carry=0, temp;
   for(i=2;i>=0;i--)
   {
      temp=(arg[i]<<1)+carry;
      if (temp>9) temp+=6;
      carry=temp>>4;
      arg[i]=temp&0xF;
   }
}

这很好用,如果你给它一个像{4,5,6}这样的数组,它会返回{9,1,2}.,问题是,如果我想移位超过一位,我必须一遍又一遍地调用这个函数。有没有什么聪明的方法可以一次移位超过一位,而不是先把BCD数字转换成十进制?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-23 13:12:19

如下所示,N是要移位的位数,假设N<=3,如果移位超过3 (N>3),则需要处理多位进位(例如9*(2^4) = 144):

代码语言:javascript
复制
void LShift(unsigned char *arg)
{
   int i, carry=0, temp;
   for(i=2;i>=0;i--)
   {
      temp=(arg[i]<<N)+carry; 
      arg[i]=temp%10;
      temp -= arg[i];
      carry = temp/10;
   }
}

或者,如果你想要更接近原始版本的东西:

代码语言:javascript
复制
void LShift(unsigned char *arg)
{
   int i, carry=0, temp;
   for(i=2;i>=0;i--)
   {
      temp=(arg[i]<<N)+carry;
      temp+=6 * (temp/10);
      carry=temp>>4;
      arg[i]=temp&0xF;
   }
}

还要注意(在所有版本中,包括原始版本),您可能会留下一个新的数字进位。

票数 3
EN

Stack Overflow用户

发布于 2013-07-23 13:28:45

您必须重新设计函数,使其包含要移位的位数,作为argument.And使用该参数将bcd字节移位许多位置。

代码语言:javascript
复制
void LShift(unsigned char *arg) can be modified to void LShift(unsigned char *arg,int n)

并这样做

代码语言:javascript
复制
temp=(arg[i]<<n)+carry;
票数 1
EN

Stack Overflow用户

发布于 2013-07-23 14:56:03

编写移位逻辑有点复杂,因为进位操作有点繁琐。它变成了看起来非常像移位和加法乘法实现的代码。

代码语言:javascript
复制
void LeftShiftN_1 (unsigned char arg[BCD_DIGITS], unsigned N) {
    int i, j;
    unsigned x, carry;
    unsigned char accum[BCD_DIGITS];
    memset(accum, '\0', sizeof(carry));
    for (i=BCD_DIGITS; i>0; --i) {
        x = arg[i-1];
        x <<= N;
        carry = 0;
        for (j=i; j>=0; --j) {
            carry += accum[j-1] + x % 10;
            x /= 10;
            accum[j-1] = carry % 10;
            carry /= 10;
        }
    }
    memcpy(arg, accum, sizeof(accum));
}

我认为从BCD转换到BCD再转换回来进行转换要简单得多,效率也高得多。我以一种简单的方式实现,我确信转换操作可以优化。

代码语言:javascript
复制
void LeftShiftN_2 (unsigned char arg[BCD_DIGITS], unsigned N) {
    int i;
    unsigned accum;
    accum = 0;
    for (i=0; i<BCD_DIGITS; ++i) {
        accum = 10*accum + arg[i];
    }
    accum <<= N;
    for (i=BCD_DIGITS; i>0; --i) {
        arg[i-1] = accum % 10;
        accum /= 10;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17801770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档