2021SC@SDUSC
综述
模2运算是一种二进制算法,不考虑进位和借位,即模2加法是不带进位的二进制加法运算,模2减法是不带借位的二进制减法运算。
模2运算
模2加法
两个序列模二相加,即两个序列中对应位相加,不进位,相同为0,不同为1。
1+1=0 0+0=0 1+0=1 0+1=1(相同即为0,否则为1)
模2减法
减法和加法一样,按加法规则运算。
0-0=0 1-1=0 0-1=1 1-0=1(相同即为0,否则为1)
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
int k[100];//存放计算后的二进制数
char s1[100],s2[100];//输入的两个二进制数
int sum,sum1=0,sum2=0;
int len1,len2;//两个字符数组的长度
int i=0;
gets(s1);
gets(s2);
len1 = strlen(s1);
len2 = strlen(s2);
while(s1[i]!='\0')//第一个二进制数转化为十进制数
{
sum1+= pow(2,len1-1)*(s1[i]-48);
len1--;
i++;
}
i=0;
while(s2[i]!='\0')//第二个二进制数转化为十进制数
{
sum2+= pow(2,len2-1)*(s2[i]-48);
len2--;
i++;
}
i=0;
sum = sum1+sum2;//两数和
while(sum)//和转化为二进制
{
k[i] = sum%2;
sum/=2;
i++;
}
i=i-1;
while(i>=0)//输出
{
printf("%d",k[i]);
i--;
}
return 0;
}
模2乘法
多位二进制模2乘法类似于普通意义上的多位二进制乘法,或者是十进制乘法。不同之处在于后者累加中间结果(或称部分积)时采用带进位的加法,而模2乘法对中间结果的处理方式采用的是模2加法。
0×0=0 0×1=0 1×0=0 1×1=1(除11为1外,其余都为0)
代码实现
#include <stdio.h>
#include <stdlib.h>
#define LEN 64 //因子二进制位数的两倍,32位乘法结果不会超过64位
int main()
{
unsigned int a = 0x13131313;
unsigned int b = 0x23232323;
unsigned int p = 0x00000001;
unsigned int temp = 0;
unsigned int flags; //用于判断做加法时是否溢出
int i;
int rlt[LEN] ={0}; //结果数组
for(i=0; i<LEN; i++) //主循环
{
flags = 0;
if(b&p) //判断是否需要做加法
{
flags = temp;
temp += a;
}
rlt[i] = (int) temp & 1; //最低位丢弃,并保存至数组
if(temp < flags) //判断是否溢出
temp += 0x80000000;
temp >>= 1; //右移结果
p <<= 1;
}
i = LEN-1;
while(rlt[i] == 0) i--; //丢弃结果前面的0
for(; i>=0; i--) //打印结果
printf("%d", rlt[i]);
printf("\n");
return EXIT_SUCCESS;
}
模2除法
多位二进制模2除法也类似于普通意义上的多位二进制除法,但是在如何确定商的问题上两者采用不同的规则。后者按带借位的二进制除法,根 据余数减除数够减与否确定商1还是商0,若够减则商1,否则商0。多位模2除法采用模2减法,不带借位的二进制减法,因此考虑余数够减除数与否是没有意义 的。实际上,在CRC运算中,总能保证除数的首位为1,则模2除法运算的商是由余数首位与除数首位的模2除法运算结果确定。因为除数首位总是1,按照模2 除法运算法则,那么余数首位是1就商1,是0就商0。
在下面的示例中,当余数位数与除数位数相同时,才进行异或运算,余数首位是1,商就是1,余数首位是0,商就是0。当已经除了几位后,余数位数小于除数,商0,余数往右补一位,位数仍比除数少,则继续商0,当余数位数和除数位数一样时,商1,进行异或运算,得新的余数,以此至被除数最后一位。
代码实现
int divide(int a, int b){
if(!b)
throw std::runtime_error("Divided can't be zero...");
bool isNegative = false;
bool isNegtive = false;
if(getSign(a) ^ getSign(b))
isNegtive = true;
if(a < 0) a = add(~a,1);//求出a的绝对值
if(b < 0) b = add(~b,1);//求出b的绝对值
int res = 0;
while(a >= b){
res = add(res,1);
a = subtraction(a,b);
}
if(isNegative)
add(~res,1);
return res;
}
具体运算实例见@回首~阑珊