首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >8位BCD校验

8位BCD校验
EN

Stack Overflow用户
提问于 2015-03-21 04:49:00
回答 4查看 2K关注 0票数 2

我有一个8位的BCD号码,需要检查一下它是否是一个有效的BCD号码。我如何以编程方式(C/C++)实现这一点?

例如: 0x12345678有效,但0x00f00abc无效。

提前感谢!

EN

回答 4

Stack Overflow用户

发布于 2015-03-21 05:27:34

你需要检查每个4位的数量,以确保它小于10。为了提高效率,你希望在单个时间内处理尽可能多的位。

在这里,我将数字分开,在每个数字之间留一个零,然后在每个数字上加上6,并检查是否溢出。

代码语言:javascript
复制
uint32_t highs = (value & 0xf0f0f0f0) >> 4;
uint32_t lows = value & 0x0f0f0f0f;
bool invalid = (((highs + 0x06060606) | (lows + 0x06060606)) & 0xf0f0f0f0) != 0;

编辑:实际上我们可以做得更好一点。检测溢出不需要4位,只需要1位。如果我们将所有数字除以2,它会释放一点空间,我们可以一次检查所有数字。

代码语言:javascript
复制
uint32_t halfdigits = (value >> 1) & 0x77777777;
bool invalid = ((halfdigits + 0x33333333) & 0x88888888) != 0;
票数 10
EN

Stack Overflow用户

发布于 2015-03-21 05:30:53

最明显的方法是:

代码语言:javascript
复制
/* returns 1 if x is valid BCD */
int
isvalidbcd (uint32_t x)
{
    for (; x; x = x>>4)
    {
        if ((x & 0xf) >= 0xa)
            return 0;
    }
    return 1;
}

This link告诉你所有关于BCD的信息,并推荐这样的更优化的解决方案(重新工作以检查所有的数字,因此使用64位数据类型,并且未经测试):

代码语言:javascript
复制
/* returns 1 if x is valid BCD */
int
isvalidbcd (uint32_t x)
{
   return !!(((uint64_t)x + 0x66666666ULL) ^ (uint64_t)x) & 0x111111110ULL;
}
票数 3
EN

Stack Overflow用户

发布于 2015-03-21 07:33:39

对于无效的数字,它需要是10-15。这反过来意味着8+4或8+2 -低位根本无关紧要。

所以:

代码语言:javascript
复制
long mask8 = value & 0x88888888;
long mask4 = value & 0x44444444;
long mask2 = value & 0x22222222;
return ((mask8 >> 2) & ((mask4 >>1) | mask2) == 0;

不太明显的是:

代码语言:javascript
复制
long mask8 = (value>>2);
long mask42 = (value | (value>>1);
return (mask8 & mask42 & 0x22222222) == 0;

通过在遮罩之前移动,我们不需要3个不同的遮罩。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29175568

复制
相关文章

相似问题

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