从代码上理解累加器的奥秘

小作坊自主下料

近期挺好奇累加器的,好奇是怎么算出1+1=10的,在本子上画了一下

输入1输入2输出
0000
1001
0101
1110

只保留低位

输入1输入2输出低位异或
0000
1011
0111
1100

看规律异或就行
异或的规则是相同为0,不同为1

只保留高位

输入1输入2输出高位
0000
1000
0100
1111

看结果就是按与计算,结果就是高位,结合高低位,就是第一张表的结果

此时一个一位计算器就完事了

//js代码
let add = (a,b) => ((a & b) + '' + (a ^ b));
add(0,0);//=>00
add(0,0);//=>01
add(0,1);//=>01
add(1,1);//=>10

正规作坊下料

怎么看都有点不对,印象里累加器好像很大的样子,我这个好像太过简单了
一查发现我这个设计只能计算一位数据,并且无法串联计算,模块需要一个进位标识符,然后将其串起来,即可算很多位,

参考这个文章

其思想是只计算低位结果,输入两个加数和一个进位,输出一个结果和进位,将进位串入下一个输入里

//js
//a 加数1
//b 加数2
//c 是否进位

let add = (a,b,c) => {
	
	let low = a ^ b;//低位(直接结果)
	let tall = a & b;//高位(是否可能进位)
	
	let sum = low ^ c;//结果(考虑进位后的结果)
	
	//计算是否进位
	let isCarry = low & c;//计算进位+低位(直接结果)
	
	let cNext = tall | isCarry;

	return { cNext, sum };
}

add(1,1);//=>{cNext: 1, sum: 0}
add(1,0);//=>{cNext: 0, sum: 1}
add(0,0);//=>{cNext: 0, sum: 0}

此时我们就拥有一个完整功能的累加器了,实现其串联功能,只需要将add串起来,从代码上可以这样理解

//js
//累加全部,只接收二进制
let addAll = (a,b) => {
  let sa = String(a);
  let sb = String(b);
  let length = sa.length -1;
  let isCarry = 0;
  let sums = '';
  for(i = 0; i <= length; i++){
	let bita = sa[length - i];
	let bitb = sb[length - i];
	let outo = add(bita, bitb, isCarry);//调用累加器
	
	//console.log('计算输入和输出',bita,bitb,isCarry,outo)
	
	sums = outo.sum + '' + sums;
	isCarry = outo.cNext;
	//console.log('是否进位,输出的数', isCarry,sums)
  }
  
  //console.log('补上进位的数', isCarry)
  sums = isCarry + '' + sums;//补上最后一个进位
  
  console.log('运算结果',sums);
}

addAll(11,11);//=>运算结果 110
addAll(110,101);//=>运算结果 1011

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值