1.前言
在当今数字时代,我们享受着计算机带来的便利和效率,但很少有人意识到在计算机背后的神秘世界。计算机内部运算的奥秘并非仅仅是一系列简单的加减乘除,而是依托着深奥的门电路与位运算符展开的神秘舞蹈。在这篇博客中,我们将探秘计算机内部的魔法,深入剖析如何利用门电路模拟加减乘除等基本运算,揭示计算机运算背后隐藏的真相与奥秘。随我一起踏入这个神秘的世界,探寻计算机运算背后的魔法秘籍!
在计算机内部,运算并非简单地使用运算符,而是通过门电路实现的位运算符来完成。在这篇文章中,我们将深入探讨计算机底层如何模拟使用位运算实现加法,揭示其中的奥秘。
2. 加法
public static int add(int a, int b) {while (b != 0) {// 计算进位int carry = (a & b) << 1;// 异或操作得到不考虑进位的和a = a ^ b;// 将进位赋值给b,继续循环直到进位为0b = carry;}return a;}
2. 减法
和减法原理相似就是使用,5 - 3 = 5 + (-3的补码)
public static int subtract(int a, int b){b = (~b + 1);//转换为负数的补码return add(a,b);}
3.乘法
乘法我的思想: 20 * 7 = 20 * (2º + 2¹ + 2²) = 20 << 0 + 20 << 1 + 20 << 2
这是同为正数的情况下,正所谓 正正得正,负正 正负得负,负负得正,所以我就可以使用异或来实现判断同为1,异为0,然后我进行绝对值相乘即可。
public static int multiply(int a, int b){int sign = (a >> 31) ^ (b >> 31); // 确定符号位a = abs(a); // 取a的绝对值b = abs(b); // 取b的绝对值int result = 0;while (b != 0) {if ((b & 1) != 0) { // 如果 b 的最低位为1result = add(result, a); // 累加到结果中}a <<= 1; // 左移相当于乘以2b >>= 1; // 右移相当于除以2}return sign == 0? result : ~result + 1;}public static int abs(int x) {int mask = x >> 31; // 获取符号return mask == 0 ? x : ~(subtract(x,1)); // 正数不变,负数取反加一}
4.除数
public static int divide(int a, int b) {// 确定符号位int sign = (a >> 31) ^ (b >> 31);// 取绝对值a = abs(a);b = abs(b);// 处理被除数为0的情况if (b == 0) {throw new ArithmeticException("被除数不能为0");}int result = 0;for (int i = 30; i >= 0 ; i = subtract(i,1)) {if((a >> i) >= b) {//判断是否可商result |= (1 << i);//i位置变为1a = subtract(a,b << i);//余数赋值给a}}return sign == 0 ? result : ~result + 1;}