1.前言
在当今数字时代,我们享受着计算机带来的便利和效率,但很少有人意识到在计算机背后的神秘世界。计算机内部运算的奥秘并非仅仅是一系列简单的加减乘除,而是依托着深奥的门电路与位运算符展开的神秘舞蹈。在这篇博客中,我们将探秘计算机内部的魔法,深入剖析如何利用门电路模拟加减乘除等基本运算,揭示计算机运算背后隐藏的真相与奥秘。随我一起踏入这个神秘的世界,探寻计算机运算背后的魔法秘籍!
在计算机内部,运算并非简单地使用运算符,而是通过门电路实现的位运算符来完成。在这篇文章中,我们将深入探讨计算机底层如何模拟使用位运算实现加法,揭示其中的奥秘。
2. 加法
public static int add(int a, int b) {
while (b != 0) {
// 计算进位
int carry = (a & b) << 1;
// 异或操作得到不考虑进位的和
a = a ^ b;
// 将进位赋值给b,继续循环直到进位为0
b = 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 的最低位为1
result = add(result, a); // 累加到结果中
}
a <<= 1; // 左移相当于乘以2
b >>= 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位置变为1
a = subtract(a,b << i);//余数赋值给a
}
}
return sign == 0 ? result : ~result + 1;
}