模2除(按位除)
模2除做法与算术除法类似,但每一位除(减)的结果不影响其它位,即不向上一位借位。所以实际上就是异或。然后再移位移位做下一位的模2减。步骤如下:
a、用除数对被除数最高几位做模2减,没有借位。
b、除数右移一位,若余数最高位为1,商为1,并对余数做模2减。若余数最高位为0,商为0,除数继续右移一位。
c、一直做到余数的位数小于除数时,该余数就是最终余数。
【例】1111000除以1101: (先用动手多算几个 模2除法对 程序设计有很大好处)
1011———商
————
1111000-----被除数
1101———— 除数
————
010000
1101
————
01010
1101
————
111————余数
实现效果预览:
C语言实现:
/*********************************************************************
功能:对数据进行 CRC校验 输出 校验码
算法: 模二除法, 除法的一般原理,补0思想
时间: 2011 - 08 -09
地点: 中科大苏州研究院
作者: 李开国
******************************************************************** */
#include < stdio.h >
void CRC_check( long MD, long GD);
int main()
{
long MD; //
long GD; //
int tmp = 10 ;
printf( " \n\n------CRC校验码-------数据以16进制输入 " );
while (tmp -- )
{
printf( " \nPlease input 校验数据:\n>> " );
scanf( " %x " , & MD);
printf( " Please input 多项式:\n>> " );
scanf( " %x " , & GD);
CRC_check(MD,GD);
printf( " \n按任意键继续》》》》 " );
}
}
void CRC_check( long MD1, long GD1)
{
long MD = MD1 ; // 需要校验的数据
long GD = GD1; // 随机生成的多项式
long tmp; // 临时变量保存多个移位,或恢复原值信息
int count_MD; // 校验数据的 位数
int count_GD; // 多项式的 位数
int count; // 两者位数差
long tst0 = 1 ; // 判断余数最高位是否为 0
tmp = MD; // 数 MD 有多少位
for (count_MD = 0 ; MD != 0 ; count_MD ++ )
MD >>= 1 ;
MD = tmp;
tmp = GD; // 数 GD有多少位
for (count_GD = 0 ; GD != 0 ; count_GD ++ )
GD >>= 1 ;
GD = tmp ;
// 构造CRC码序列
for (tmp = 1 ; tmp < count_GD ; tmp ++ )
MD <<= 1 ;
count = count_MD - 1 ;
// 将GD 与 MD 构造等长,低位用0填充
tmp = count;
while (count -- )
{
GD <<= 1 ;
}
count = tmp;
// tst0 和 MD 求与 运算,确定MD最高位是否为 1,确定是否应该求模
tmp = count_GD + count_MD - 1 ;
while ( -- tmp)
tst0 <<= 1 ;
// MD == 11 0101 1011 0000 ,模二除法的实现
for ( ; count >= 0 ; count -- )
{
// printf("tst0&MD==%x, tst0==%x tst0&MD=%d \n\n",tst0&MD,tst0,(tst0==tst0&MD));
if (tst0 == (tst0 & MD))
{
MD ^= GD ; // 少量修改可以实现 商的计数
}
tst0 >>= 1 ;
GD >>= 1 ;
}
printf( " CRC校验码:0x%X " ,MD); // 输出CRC校验码
}
算法: 模二除法, 除法的一般原理,补0思想
时间: 2011 - 08 -09
地点: 中科大苏州研究院
作者: 李开国
******************************************************************** */
#include < stdio.h >
void CRC_check( long MD, long GD);
int main()
{
long MD; //
long GD; //
int tmp = 10 ;
printf( " \n\n------CRC校验码-------数据以16进制输入 " );
while (tmp -- )
{
printf( " \nPlease input 校验数据:\n>> " );
scanf( " %x " , & MD);
printf( " Please input 多项式:\n>> " );
scanf( " %x " , & GD);
CRC_check(MD,GD);
printf( " \n按任意键继续》》》》 " );
}
}
void CRC_check( long MD1, long GD1)
{
long MD = MD1 ; // 需要校验的数据
long GD = GD1; // 随机生成的多项式
long tmp; // 临时变量保存多个移位,或恢复原值信息
int count_MD; // 校验数据的 位数
int count_GD; // 多项式的 位数
int count; // 两者位数差
long tst0 = 1 ; // 判断余数最高位是否为 0
tmp = MD; // 数 MD 有多少位
for (count_MD = 0 ; MD != 0 ; count_MD ++ )
MD >>= 1 ;
MD = tmp;
tmp = GD; // 数 GD有多少位
for (count_GD = 0 ; GD != 0 ; count_GD ++ )
GD >>= 1 ;
GD = tmp ;
// 构造CRC码序列
for (tmp = 1 ; tmp < count_GD ; tmp ++ )
MD <<= 1 ;
count = count_MD - 1 ;
// 将GD 与 MD 构造等长,低位用0填充
tmp = count;
while (count -- )
{
GD <<= 1 ;
}
count = tmp;
// tst0 和 MD 求与 运算,确定MD最高位是否为 1,确定是否应该求模
tmp = count_GD + count_MD - 1 ;
while ( -- tmp)
tst0 <<= 1 ;
// MD == 11 0101 1011 0000 ,模二除法的实现
for ( ; count >= 0 ; count -- )
{
// printf("tst0&MD==%x, tst0==%x tst0&MD=%d \n\n",tst0&MD,tst0,(tst0==tst0&MD));
if (tst0 == (tst0 & MD))
{
MD ^= GD ; // 少量修改可以实现 商的计数
}
tst0 >>= 1 ;
GD >>= 1 ;
}
printf( " CRC校验码:0x%X " ,MD); // 输出CRC校验码
}