【离散数学】实践一 用C语言实现二进制加法器

题目以及要求

每个学生利用 C 语言独自完成设计一个 8 位加法器,计算只用非与或(!, &&,‖)三种逻辑运算实现。(C 语言的布尔数据类型:bool,参考: https://www.javatpoint.com/c-boolean)

要求:输入:两个加数(8 位的二进制数)

输出:加数的和(8 位或者 9 位的二进制数)


参考资料

加法器原理图释:

半加法器

全加法器

两个三位二进制数相加的例子(由一个半加法器和两个全加法组成)

加法器文字解释:

  1. 图片中的代表第一个数的第一位代表第一个数的第2位....代表第i + 1位;

  1. 同理可得的含义;

  1. 代表求和后的二进制数的第 i + 1位

  1. 代表相加后再这位上的进位情况

两个有限位的二进制数相加均可以看做成由若干个全加器和半加器组成,半加器负责运算出第一位的和情况和进位情况,也就是(当 i = 0)。而后面若干位均是由全加器负责,全加器有三个入口参数,有两个结果参数将传入下一个加法器。


实验原理

应用半加器和全加器的有效组合来达到将两个有限位的二进制数相加,并且得出一个有限位的结果。同时采用了与“&& ”、非“ ! ”的逻辑实现,由于不能使用异或” ^ ”,故没有设计成超前加法器来提升其效率。


加法器设计与实现

该加法器的逻辑电路图:

两个八位的二进制数相加的加法器

设计与实现:

  • First数组:用于存第一个数的二进制形式

  • Second数组:用于存第二个数的二进制形式

  • Sum数组:用于存两数相加的二进制形式

  • CarryBit数组:用于存两数相加进位情况,0为未进位,1为已进位

  • RevCarry数组:用于存放carryBit数组的非

  • 运算式子:

  • 若i = 0

  • Sum [ 0 ] = ( first[ 0 ] + second [ 0 ] ) * revCarry[ 0 ]

  • 若i > 0

  • Sum [ i ] = ( (first [ i ] + second [ i ]) * revCarry[ i ] ) + carryBit[ i - 1]


运行界面,结果截图


源代码:adder.cpp

//每个学生利用 C 语言独自完成设计一个 8 位加法器,计算只用非与或(!,
//&&,‖)三种逻辑运算实现。
//要求:输入:两个加数(8 位的二进制数)
//输出:加数的和(8 位或者 9 位的二进制数)
#include <stdio.h>
#include <iostream>
using namespace std;

const int N1 = 7;
const int N2 = 8;

int first[N1], second[N1], carryBit[N1], revCarry[N1], sum[N2];
int n,m;

//判断输入的数字是否合法 
void isLegal(int a[])
{
    for(int i = N1; i >= 0; i--)
    {
        if((a[i] != 0 && a[i] != 1))
        {
            printf("输入字符%d错误!请输入二进制数",a[i]);
            break;
        }
        else  continue;
    }
}
//进位情况取反
void reverseCarry(int b[])
{
    for(int i = 0; i <= N1; i++)
    {
        if(b[i] == 0) revCarry[i] = 1;
        else revCarry[i] = 0;    
    }    
} 
int main(){
    cout << "请输入第一个二进制数" << endl;
    scanf("%d",&n);
    for(int i = 0; i <= N1; i++){
        first[i] = n % 10;
        n = n /10;
    }
    isLegal(first);
    cout << "请输入第二个二进制数" << endl;
    scanf("%d",&m);
    for(int i = 0; i <= N1; i++){
        second[i] = m % 10;
        m = m /10;
    }
    isLegal(second);
    for(int i = 0; i <= N1; i++)
    {
        carryBit[i] = first[i] * second[i];
//    可验证carry数组里面的数字分布的情况 
//        printf("第%d位carry是%d\n",i,carryBit[i]);
    }
    reverseCarry(carryBit);
//    可验证是否已经取反 
//    for(int i = 0; i <= N1; i++)
//    {
//        printf("取反后的Carry第%d位是%d\n",i,revCarry[i]);
//    }
    for(int i = 0; i <= N2; i++)
    {
        if(i == 0)
        { 
        sum[i] = (first[i] + second[i]) * revCarry[i];
        }
        else if(i <= 7) 
        {
        sum[i] = ((first[i] + second[i]) * revCarry[i]) + carryBit[i - 1];
        }
        else sum[i] = carryBit[i - 1];
    }
    cout << "和是" << endl;
    for(int i = N2; i >= 0 ; i--) printf("%d",sum[i]);
    return 0;
}

结语

如果有疑问欢迎大家留言讨论,你如果觉得这篇文章对你有帮助可以给我一个免费的赞吗?我们之间的交流是我最大的动力!

猜你喜欢

转载自blog.csdn.net/Zchengjisihan/article/details/129659140