【logisim】如何不用加号实现加法函数——低级版

大家好, 借着如何不用加号实现加法的由头, 前阵子已经写过这些了:

  1. 为了阅读代码,可以运用IDEA自带的重构技巧, 把代码的不同形式进行转换.
    J K L,公众号:K字的研究【预热】如何不用加号实现加法函数?
  2. 减治特点则是每次规模减少的是个常数,比如这里每次少1.
    J K L,公众号:K字的研究【详解】如何不用加号实现加法函数?

不过感觉,这个话题能写的还没写完,今天继续.

还是研究这个问题,不用上次的excel了, 这次换了个工具。至于什么工具,暂时保密.

上篇回顾

前面一篇得到两个东西:

  • 与,a&b 计算进位 C(arry)
  • 异或, a^b 计算当前位的和 S(um)

这里我们引入一个限制,入参限制为只能是10,  借助一个Pair作为返回值同时返回C和S,可以得到这样一个函数:

Pair<Integer, Integer> halfAdd(int a, int b) {
    return Pair.of(a&b, a^b);
}

这个函数的入参只有4种情况,真值表如下:

0  0 (0,0)
0  1 (0,1)
1  0 (0,1)
1  1 (1,0)

在这种真值表下, 这个函数,其实相当于一个半加器(Half Adder).

半加器

半加器的功能是, 输入两个bit,产生一个和S,一个进位C.

这东西一般是拿来组电路用的,逻辑电路如下:

【logisim】如何不用加号实现加法函数——低级版

为什么这个东西叫半加呢?因为他不是全家.

【logisim】如何不用加号实现加法函数——低级版

全加器(Full adder)

半加器的入参是两个, 全加器除了这两个, 还需要考虑低位进位值Cin,一共是3个入参,出参还是两个.为了区分记为CoutS.

逻辑电路图如下,红框里是上面的半加器,整个橙色的构成全加器.

【logisim】如何不用加号实现加法函数——低级版

全加器的3入2出写成对应函数的形式是:

Pair<Integer, Integer> fullAdd(int a, int b, int c) {
        var v = halfAdd(a, b);
        var lc = v.getLeft();
        var ls = v.getRight();
        return Pair.of((c & ls) | lc, ls ^ c);
}

多位加法器

现在这个全加器只支持1个bit的加法, 如果要支持多位,比如4位,8位,32位的加法, 可以采用串联或者并联.

串联比较简单,大概下图这样,构成了一个4位全加器. 画面大小有限, 换了一个原生组件.那个正方形框代表全加器,3入2出的接口没变. 我们把上一个全加器的cout连到下一个全加器的cin上去.

【logisim】如何不用加号实现加法函数——低级版
  • 一共是4个加法器串联起来
  • 左边红框里是4个输入bit
  • 中间红框是另一个4bit输入
  • 最右侧是输出结果.
  • 低位在上面

加法函数写法

当然, 这个4位加法器也是可以用程序模拟的.

 int add(int a, int b) {
        int n = 4;
        int carry = 0;
        int result = 0;

        for (int i = 0; i < n; i++) {
            int an = (a >> i) & 1;
            int bn = (b >> i) & 1;
            
            var v = fullAdd(an, bn, carry);
            
            carry = v.getLeft();
            int s = v.getRight();
            
            result |= s << i;
        }
        return result;
 }

利用第0篇提到过的劣化代码技巧, 这个代码可以改成这个样子.

    static int add(int a, int b) {
        int carryIn = 0;
        int sum = 0;

        for (int i = 0; i < 32; i++) {
            var carrayOut = (carryIn & ((a >> i) & 1 ^ (b >> i) & 1)) | (a >> i) & 1 & ((b >> i) & 1);
            sum |= ((a >> i) & 1 ^ (b >> i) & 1 ^ carryIn) << i;
            carryIn = carrayOut;
        }
        return sum;
    }

看起来难懂了,但是其实还是那回事.不过说起来,i++也算是加号. 倒也挺好解决的, 就不修了.

正文开始

是的,没看错,正文开始.

前面的全是预热,毕竟已经解析过了. 今天,是来推荐画图工具的,一个相逢恨晚的工具.

上面的图都是用Logisim画的.而且,这东西还能模拟.请看下面的动图.

  • 方框是输入,点击会从1变0,从0变1.
  • 圆形是输出
【logisim】如何不用加号实现加法函数——低级版
【logisim】如何不用加号实现加法函数——低级版

整个软件大小十分惊人,一共6M.

软件图标

【logisim】如何不用加号实现加法函数——低级版
logisim

认准这个图就行.

下载地址

认准官网Logisim (cburch.com)[1].

【logisim】如何不用加号实现加法函数——低级版

支持平台

对了, 这货好像是全平台的,mac都支持.甚至还有一个jar格式的,怀疑Linux也可以?

有啥用

这么轻量级的软件, 还是免费的,谁还管他有啥用啊?下到就是赚到.

虽然社畜没啥用,但是可以推荐给身边还在上学的小朋友用啊.

反正也上不了当,连硬盘都占不了多大.年轻时候如果知道有这个,学习时候舒服很多的.

推荐完毕,今天就到这里,这里是K字的研究,一个Java程序员的日常分享.再见.

参考资料

[1]

Logisim (cburch.com): http://www.cburch.com/logisim/


原文始发于微信公众号(K字的研究):【logisim】如何不用加号实现加法函数——低级版

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/24710.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!